在1.x我们可以使用ngAnimate来检测我们何时离开或进入特定路由.此外,我们能够将行为应用于他们:

animateApp.animation('.myElement', function(){

    return {

        enter : function(element, done) {
            //Do something on enter
        },

        leave : function(element, done) {
            //Do something on leave
        }
    };

)};

产生了这样的产品:http://embed.plnkr.co/uW4v9T/preview

我想用Angular 2.0做一些类似的事情,我觉得我已经很接近了...

接下来,我在主应用程序组件中创建了一个简单的路由,用于控制homeabout组件之间的导航.

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: '/'})
])

目前,我能够捕捉到路由在从一个组件移动到下一个组件时实例化或销毁了特定组件的时间.这很好,但当previous组件的值为destroyed时,我无法在下一个组件初始化之前应用on leave转换动画.

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});
    }

}

似乎有一个解决办法,就是使用promise .棱角分明.io的API预览他们声明:

If onDeactivate returns a promise, the route change will wait until the promise settles.

If onActivate returns a promise, the route change will wait until the promise settles to instantiate 和 activate child components.

https://angular.io/docs/ts/latest/api/

I am super br和 new to promises so I mashed this together into my code which solved the problem of my current component being destroyed on initialization of the next one, but then it never gets destroyed, it only creates a new instance of it. Every time I navigate back to it, it will create a new instance resulting in multiple copies.

onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {

    function ani(){
      TweenMax.fromTo($(".title"), 1, {opacity: 1}, {opacity: 0});
    }

    var aniPromise = ani();

    aniPromise.then(function (ani) {
        ani();
    });

}

So to recap, the router should be able to wait for the current component to finish it's business before destroying it 和 initializing the next component.

I hope that all makes sense 和 I really appreciate the help!

推荐答案

正如您从文档中引用的,如果任何一个钩子返回一个promise ,它将等到它完成后再移动到下一个,因此您可以轻松地返回一个基本上什么都不做的promise ,然后等待一秒钟(或者根据需要等待多长时间).

 onActivate(next: ComponentInstruction, prev: ComponentInstruction) {
    TweenMax.fromTo($(".title"), 1, {opacity: 0}, {opacity: 1});
    return new Promise((res, rej) => setTimeout(() => res(1), 1000));
  }

  onDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
    TweenMax.fromTo($(".title"), 1, {opacity:1}, {opacity: 0});
    return new Promise((res, rej) => setTimeout(() => res(1), 1000));
  }

注意,我返回了一个运行setTimeout的promise .我们等待一秒钟,让动画有足够的时间完成.

我真的不喜欢使用设置超时,所以我们也可以使用我个人最喜欢的可观测值.

return Rx.Observable.of(true).delay(1000).toPromise();

在这里,我传递一个随机值(在本例中为true),并将其延迟一秒钟,最后将其转换为Promise.是的,它最终是一个promise ,但我不会直接使用它.

下面是一个plnkr的例子(希望是你想要的).

PS:如果有时它抱怨找不到Rx的路径,只需不断刷新,直到它工作(我手动添加了Rx.js,这对plnkr来说有点沉重).

Typescript相关问答推荐

具有匹配键的通用对象界面

如何将函数类型应用到生成器?

将对象属性路径描述为字符串数组的类型

如何使用另一个类型的属性中的类型

如何将http上下文附加到angular中翻译模块发送的请求

TypScript如何在 struct 上定义基元类型?

参数类型undefined不能分配给参数类型字符串|未定义

用泛型类型覆盖父类函数导致类型y中的Property x不能赋给基类型Parent中的相同属性."'''''' "

将值添加到具有不同类型的对象的元素

扩展函数签名中的参数类型,而不使用泛型

Angular 错误NG0303在Angular 项目中使用app.Component.html中的NGFor

打印脚本中的动态函数重载

Angular NgModel不更新Typescript

路由链接始终返回到

防止重复使用 Select 器重新渲染

从以下内容之一提取属性类型

对于VUE3,错误XX不存在于从不存在的类型上意味着什么?

可以将JS文件放在tsconfig';s includes/files属性?或者,我如何让tsc判断TS项目中的JS文件?

如何在TypeScript中将元组与泛型一起使用?

无法使用prisma中的事务更新记录