Как применить разные анимации между разными маршрутами в угловых 2

У меня есть тестовое приложение сборки с Angular 2, я успешно применил одну анимацию между сменой маршрута

state('default', style({
    opacity: 1,
    transform: 'scale(1) translateY(0)'
})),
transition('void <=> default', [
    style({ opacity: 0, transform: 'scale(.9) translateY(-20px)' }),
    animate('.2s')
])

Но я также хочу другую анимацию, когда страница списка меняется на страницу элемента, например, щелкнуть героя внутри списка героев, поэтому я сделал это

state('childActivate', style({
    opacity: 1,
    transform: 'scale(1) translateY(0)'
})),
transition('childActivate => void', [
    animate('1.2s', style({
        transform: 'scale(0.9)  translateY(-120px)',
        opacity: 0
    }))
])

Я попытался установить состояние "childActivation" после того, как я щелкнул элемент и перед навигацией:

onHeroSelected(heroEvent: Hero) {
    this.animState = "childActivate";
    this.router.navigate(['/hero-detail', heroEvent.id]);
}

но не имеет никакого эффекта.

Как я могу получить несколько анимаций между маршрутами?

1 ответ

Установка состояния "childActivate" не имеет никакого эффекта, потому что компонент уничтожается на следующем этапе обнаружения изменений, поэтому вместо этого состояние переключается на void.

Вот как я решил эту проблему: я задерживаю изменение маршрута еще на 1 цикл обнаружения изменений. Для этого я использую CanDeactivate Guard, который прислушивается к обещанию разрешить проблему.

Проверьте мой plnkr: https://embed.plnkr.co/cOeDfXCetaYuXFaZ7WeO/

В определениях маршрутов я добавляю:

canDeactivate: [CanDeactivateAfterChangeDetectionGuard]

Это CanDeactivate Guard:

@Injectable()
class CanDeactivateAfterChangeDetectionGuard implements CanDeactivate<WaitForChangeDetection> {
  canDeactivate(component: WaitForChangeDetection): Promise<boolean> {
    return component.waitForChangeDetection();
  }
}

который работает с любым компонентом, реализующим этот интерфейс:

declare abstract class WaitForChangeDetection {
  abstract waitForChangeDetection(): Promise<boolean>;
}

Я создал базовый компонент с реализацией этого интерфейса по умолчанию

@Component({})
class WaitForChangeDetectionImpl implements AfterViewChecked, WaitForChangeDetection {
  constructor(private cdRef: ChangeDetectorRef){
    this.viewChecked$ = new Subject<void>();
  }

  viewChecked$: Subject<void>;
  waitForChangeDetection(): Promise<boolean>{
    this.cdRef.detectChanges();
    return new Promise((resolve) => this.viewChecked$.subscribe(() => resolve(true)));
  }

  ngAfterViewChecked(){
    this.viewChecked$.next();
  }
}

Таким образом, вы можете расширить этот компонент, чтобы обеспечить функциональность для работы с защитой для любого компонента.

@Component({})
class ComponentA extends WaitForChangeDetectionImpl {
...
Другие вопросы по тегам