Animações de transição de página com o roteador Angular 2.0 e a interface do componente prometem
No Angular 1.x, podemos usar o ngAnimate para detectar quando estamos saindo ou entrando em uma rota específica. Além disso, somos capazes de aplicar comportamentos a eles:
animateApp.animation('.myElement', function(){
return {
enter : function(element, done) {
//Do something on enter
},
leave : function(element, done) {
//Do something on leave
}
};
)};
Resultando em um produto como este:http://embed.plnkr.co/uW4v9T/preview
Gostaria de fazer algo semelhante com o Angular 2.0 e sinto que estou bem perto ...
Então, aqui vai, eu criei um roteador simples no componente principal do aplicativo que controla a navegação entre oscasa esobre componentes.
import { bootstrap, bind, Component, provide, View } from 'angular2/angular2';
import {RouteConfig, RouteParams, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, APP_BASE_HREF, ROUTER_BINDINGS} from 'angular2/router'
/////////////////////////////////////////////////////////////////
// Home Component Start
/////////////////////////////////////////////////////////////////
@Component({
selector: 'home-cmp'
})
@View({
template: `
<h2 class="title">Home Page</h2>
`
})
class HomeCmp implements OnActivate, onDeactivate{
onActivate(next: ComponentInstruction, prev: ComponentInstruction) {
console.log("Home Page - initialized");
}
onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
console.log("Home Page - destroyed");
}
}
/////////////////////////////////////////////////////////////////
// Home Component End
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
// About Component Start
/////////////////////////////////////////////////////////////////
@Component({
selector: 'about-cmp'
})
@View({
template: `
<h2 class="title">About Page</h2>
`
})
class AboutCmp implements OnActivate, onDeactivate {
onActivate(next: ComponentInstruction, prev: ComponentInstruction) {
console.log("About Page - initialized");
}
onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
console.log("About Page - destroyed");
}
}
/////////////////////////////////////////////////////////////////
// About Component End
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
// Main Application Componenent Start
/////////////////////////////////////////////////////////////////
@Component({
selector: 'my-app'
})
@View({
template: `
<div>
<h1>Hello {{message}}!</h1>
<a [router-link]="['./HomeCmp']">home</a>
<a [router-link]="['./AboutCmp']">about</a>
<hr>
<router-outlet></router-outlet>
</div>
`,
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{path: '/', component: HomeCmp, as: 'HomeCmp'},
{path: '/about', component: AboutCmp, as: 'AboutCmp'}
])
export class App {
}
/////////////////////////////////////////////////////////////////
// Main Application Componenent End
/////////////////////////////////////////////////////////////////
bootstrap(App, [
ROUTER_BINDINGS,
ROUTER_PROVIDERS,
ROUTER_DIRECTIVES,
provide(APP_BASE_HREF, {useValue: '/'})
])
No momento, sou capaz de capturar quando o roteador instancia ou destrói um componente em particular quando ele se move de um para o outro. Isso é ótimo, mas quando oanterior componente édestruído Não consigo aplicar umde licença animação de transição antes que o próximo componente seja inicializado.
class HomeCmp implements OnActivate, onDeactivate{
onActivate(next: ComponentInstruction, prev: ComponentInstruction) {
//This works
TweenMax.fromTo($(".title"), 1, {opacity: 0}, {opacity: 1});
}
onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
//This get ignored
TweenMax.fromTo($(".title"), 1, {opacity: 0}, {opacity: 1});
}
}
Parece que existe uma solução para isso usando promessas. A visualização da API do Angular.io indica:
Se onDeactivate retornar uma promessa, a alteração de rota aguardará até que a promessa seja estabelecida.
e
Se onActivate retornar uma promessa, a alteração de rota aguardará até que a promessa seja estabelecida para instanciar e ativar os componentes filhos.
https://angular.io/docs/ts/latest/api/
Eu sou super novo em promessas, então juntei tudo isso no meu código, o que resolveu o problema do meu componente atual ser destruído na inicialização do próximo, mas depoisNunca é destruído, ele cria apenas uma nova instância. Sempre que eu voltar a ele, ele criará uma nova instância resultando em várias cópias.
onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
function ani(){
TweenMax.fromTo($(".title"), 1, {opacity: 1}, {opacity: 0});
}
var aniPromise = ani();
aniPromise.then(function (ani) {
ani();
});
}
Então, para recapitular, o roteador deve poder aguardar a conclusão do componente atual.o negócio antes de destruí-lo e inicializar o próximo componente.
Espero que tudo faça sentido e eu realmente aprecio a ajuda!