在 Angular 5 中禁用 zone.js 后,ngOnInit 未触发

Posted

技术标签:

【中文标题】在 Angular 5 中禁用 zone.js 后,ngOnInit 未触发【英文标题】:ngOnInit is not triggering after disabling zone.js in Angular 5 【发布时间】:2018-04-25 16:11:36 【问题描述】:

我最近将我的 Angular 应用程序从 4.3 升级到了 5.0,并尝试使用其中的一些新功能。其中之一是从 zone.js 中删除依赖关系。

ma​​in.ts:

platformBrowserDynamic().bootstrapModule(AppModule, 
  ngZone: 'noop',
);

组件:

import  ApplicationRef, Component  from '@angular/core';
import  Router, NavigationEnd  from '@angular/router';
import  Subscription  from 'rxjs/Rx';

import  MenuService  from '../../services/menu.service';

@Component(
  selector: 'ba-menu',
  templateUrl: './baMenu.html',
  styleUrls: ['./baMenu.scss'],
)
export class BaMenu 
  menuItems: any[];
  protected _menuItemsSub: Subscription;
  protected _onRouteChange: Subscription;

  constructor(public _router: Router, public _service: MenuService, public app: ApplicationRef) 
    console.log('constructor triggered'); //This worked
    this.app.tick();
  


  ngOnInit(): void 
    console.log('ngOnInit() triggered'); //This doesn't worked
    this._onRouteChange = this._router.events.subscribe((event) => 

      if (event instanceof NavigationEnd) 
        if (this.menuItems) 
          this.selectMenuAndNotify();
         else 
          // on page load we have to wait as event is fired before menu elements are prepared
          setTimeout(() => this.selectMenuAndNotify());
        
      
    );

    this._menuItemsSub = this._service.menuItems.subscribe(this.updateMenu.bind(this));
  

  public ngOnDestroy(): void 
    console.log('ngOnDestroy() triggered'); //This worked
    this._onRouteChange.unsubscribe();
    this._menuItemsSub.unsubscribe();
  


在我的组件中,ngOnDestroy() 事件被触发,但 ngOnInit() 没有被触发。而且由于 ngOnInit() 不起作用,_onRouteChange 永远不会被初始化,我在 ngOnDestroy 内的 this._onRouteChange.unsubscribe(); 行上收到错误。

错误:

zone.js:690 未处理的承诺拒绝:无法读取属性 undefined 的“取消订阅”;区域:;任务:Promise.then; 值:TypeError:无法读取未定义的属性“取消订阅”

【问题讨论】:

您找到原因了吗?尽管一切都正确实施,但我也遇到了在 ngOnInit 之前调用 ngOnDestroy 的问题。 【参考方案1】:

您尚未在组件代码中实现OnInit

//Change here
export class BaMenu implements OnInit 
  menuItems: any[];
  protected _menuItemsSub: Subscription;
  protected _onRouteChange: Subscription;

  ngOnInit() 
     //Some code
  
  //Some code


【讨论】:

你不需要在 typescript 中指定一个组件implement OnInit。只需将ngOnInit() 方法添加到组件即可。 Per the Angular docs,Angular 将调用生活方式钩子如果已定义。添加 implement OnInit 仅对 IDE 中的类型检查有用。

以上是关于在 Angular 5 中禁用 zone.js 后,ngOnInit 未触发的主要内容,如果未能解决你的问题,请参考以下文章

angular2 zone.js 进行自动 sock.js 调用

Angular ZoneJS 原理

Webpack将两个应用程序捆绑在一个捆绑包中,Angular需要Zone.js

Angular 需要 Zone.js polyfill。使用系统js我面临这个问题

angular2 脏检查series1-Zone.js

Angular 7:ng serve 工作,但控制台显示 Zone.js 错误并且应用程序不会加载