Угловая /4 - Не работает анимация маршрута

Я пытаюсь реализовать анимацию маршрута в проекте Angular CLI, используя Angular/4. Я пытался следовать этому руководству, но с ограниченным успехом.

Мой код читается

/src/app/_animations/fadein.animation.ts

import { trigger, state, animate, transition, style } from '@angular/animations';

export const fadeInAnimation =
// trigger name for attaching this animation to an element using the 
[@triggerName] syntax
    trigger('fadeInAnimation', [

        // route 'enter' transition
        transition(':enter', [
         // css styles at start of transition
        style({ opacity: 0 }),
         // animation and styles at end of transition
        animate('3000ms', style({ opacity: 1 }))
    ]),
]);

/src/app/dashboard/dashboard.component.ts

import { Component, OnInit } from '@angular/core';
import { SlimLoadingBarService } from 'ng2-slim-loading-bar';

// import fade in animation
import { fadeInAnimation } from './../_animations/fadein.animation';

import { PickJob } from './../pick-jobs/pick-job';
import { PickJobService } from './../pick-jobs/pick-job.service';
import { FlashService } from './../flash/flash.service';

@Component({
    templateUrl: './dashboard.component.html',
    styleUrls: ['./dashboard.component.css'],
    animations: [fadeInAnimation],
    host: { '[@fadeInAnimation]': '' }
})
export class DashboardComponent {}

/src/app/dashboard/dashboard.component.html

<div class="container_flex">
    <div class="row">
        <div class="col-md-12">
            <div class="btn btn-block btn-primary block shadow">
                Print Next Pick Job
            </div>
            <a class="btn btn-block btn-danger shadow" routerLink="/pick-jobs" routerLinkActive="menu-active">
                List Pick Jobs
            </a>
            <a class="btn btn-block btn-warning shadow" routerLink="/cages/assign" routerLinkActive="menu-active">
                Print Pick Cage Labels
            </a>
        </div>
    </div>
</div>

/src/app/app.module.ts

...
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
...
@NgModule({
  imports: [    
      ...
      BrowserAnimationsModule,
      ...

Анимация никогда не запускается еще, завершилась до загрузки страницы. Не уверен, что. Может ли кто-нибудь обнаружить ошибку в моем коде? Любые советы высоко ценится

Ответы

Ответ 1

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

Определите свою анимацию и маршруты, к которым она применяется:

const fadeIn = [
  query(':leave', style({ position: 'absolute', left: 0, right: 0, opacity: 1 })),
  query(':enter', style({ position: 'absolute', left: 0, right: 0, opacity: 0 })),
  query(':leave', animate('1s', style({ opacity: 0 }))),
  query(':enter', animate('1s', style({ opacity: 1 })))
]

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  /* Allow CSS in this component to cascade down to child components */
  encapsulation: ViewEncapsulation.None,
  animations: [
    trigger('routerAnimations', [
      transition('* => *', fadeIn)
    ])
  ]
})

Аннотируйте свою розетку маршрутизатора в своем шаблоне:

<div class="page" [@routerAnimations]="prepareRouteTransition(outlet)">
  <router-outlet #outlet="outlet"></router-outlet>
</div>

Назад в приложении app.component.ts реализует prepareRouteTransition(outlet):

prepareRouteTransition(outlet) {
    const animation = outlet.activatedRouteData['animation'] || {};
    return animation['value'] || null;
}

Если вам нужна настраиваемая анимация в зависимости от того, какой маршрут идет/идет, вам нужно добавить некоторые метаданные к вашим маршрутам. Посмотрите, как Матиас Нимела разговаривает на ng-conf 2017 здесь для получения дополнительной информации, но его демонстрационный проект содержит рабочий пример.

Ответ 2

Да, сначала это легко и любопытно тонко.

Не используйте свойство host компонента. Это ничего не делает для вас.

Вместо этого вы должны добавить синтетическое свойство @yourTrigger к @yourTrigger "хоста" компонента, который вы хотите оживить. Если у этого компонента есть селектор, который написан в шаблоне как <app-dashboard>, то то, что вы пытаетесь сделать, это добавить "атрибут": <app-dashboard @yourTrigger>

Вы можете сделать это в самом компоненте с помощью @HostBinding:

@Component({
    templateUrl: './dashboard.component.html',
    styleUrls: ['./dashboard.component.css'],
    animations: [routeAnimation],
})
export class DashboardComponent {
    @HostBinding('@routeAnimation') routeAnimation = true;
}

@HostBinding устанавливает привязку к элементу узла компонента. Это тот же самый элемент, с которым вы обращаетесь :host в вашем шаблоне CSS.

Обратите внимание, что вам нужно как свойство animations для компонента, так и декоратор @HostBinding. Значение HostBinding должно быть триггером, который вы используете в анимации, fadeInAnimation в fadeInAnimation. routeAnimation всегда называют этот триггер routeAnimation и я не уверен, насколько это особенное, но это, вероятно, хорошая практика.