Angular2 生命周期钩子方法中的变更检测

Posted

技术标签:

【中文标题】Angular2 生命周期钩子方法中的变更检测【英文标题】:Angular2 change detection in lifecycle hook methods 【发布时间】:2017-02-20 23:58:28 【问题描述】:

我想在 ngOnInit() 中显示一个微调器,并在 ngAfterViewInit() 中隐藏它。 但这不起作用:

没有 setTimeout(),什么都不会发生 使用 setTimeOut(),微调器显示和隐藏(闪烁),但在 ngAfterViewInit() 之后

http://plnkr.co/edit/M1g7DT1Eks2gtuSXi1B1?p=preview

在此示例中,微调器组件 (spinner.ts) 是一个更改背景颜色的 div 标签。

import Component, Input from '@angular/core'

@Component(
  selector: 'my-spinner',
  template: `
    <div [style.background-color]="status ? 'red' : 'yellow'" >
      spinner is status
    </div>
  `,
)
export class MySpinner 
  @Input() status: boolean;

  status:boolean;
  constructor() 
    this.status = false;
  

  getColor() 
    if (status) 
      return "red";
     else 
      return "yellow";
    
  

  ngOnChanges(changes: [propertyName: string]: SimpleChange) 
        for (let propName in changes) 
            let chng = changes[propName];
            let cur  = JSON.stringify(chng.currentValue);
            let prev = JSON.stringify(chng.previousValue);
            console.trace(`$propName: currentValue = $cur, previousValue = $prev`);
        
    

在点击“链接到我的组件”(mycomponent.ts) 时,我希望 ngOnInit() 和 ngAfterViewInit() 之间的背景颜色微调器为红色。

import Component, Input, ApplicationRef from '@angular/core';
import AppService from './appservice';

@Component(
  selector: 'my-component',
  template: `
    <div>
      This is my component!
    </div>
  `,
)
export class MyComponent 

  constructor(private appSvc: AppService) 

  

  ngOnInit(): void 

    this.appSvc.setVisible(true);
    console.log('MyComponent - ngOnInit');
  

  ngAfterViewInit() 
    var start = new Date().getTime();
        for (var i = 0; i < 1e7; i++) 
            if ((new Date().getTime() - start) > 10000)
                break;
            
        

    //setTimeout(() =>  this.appSvc.setVisible(false));
    this.appSvc.setVisible(false);

    console.log('MyComponent - ngAfterViewInit');
  


解决办法是什么?


更新

我更新了示例 http://plnkr.co/edit/M1g7DT1Eks2gtuSXi1B1?p=preview 以使用 observable。

我将微调器设置为在 ngOnInit() 中显示,但微调器组件的 ngOnChanges() 在 ngAfterViewInit() 之后调用

日志控制台是:

VM437 AppService - setVisible - true  
VM439 mycomponent.ts!transpiled:33 MyComponent - ngOnInit  
VM439 mycomponent.ts!transpiled:37 MyComponent - ngAfterViewInit -begin  
VM439 mycomponent.ts!transpiled:47 MyComponent - ngAfterViewInit -end  
**VM440 spinner.ts!transpiled:38 status: currentValue = true, previousValue = fals**  
VM437 appservice.ts!transpiled:27 AppService - setVisible - false  
VM439 mycomponent.ts!transpiled:45 Observable Complete  
**VM440 spinner.ts!transpiled:38 status: currentValue = false, previousValue = true**

所以在生命周期钩子方法中似乎没有立即更改检测?对还是错?

【问题讨论】:

解释一下在这两个生命周期钩子中显示和隐藏元素的目的是什么? 这主要是为了尽快显示微调器(在 ngOnInit() 中),但它仅在 ngAfterViewInit() 之后显示,因此我的问题是我更新我的问题并更改示例以使用可观察的 【参考方案1】:

为了实现这一点,我认为最好将微调器直接作为非角度组件放在&lt;my-app&gt; 标签内。通过这种方式,您可以获得一个在应用程序完全加载之前显示的微调器。

如果您尝试使用 Angular 组件来实现此目的,则在加载 Angular 应用程序之前,微调器不会显示,并且在加载时微调器在那一刻是无用的。

【讨论】:

以上是关于Angular2 生命周期钩子方法中的变更检测的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 应用程序中 NgOnInit 生命周期钩子中移动方法的问题

Angular 生命周期钩子,让你掌控每个关键时刻!

Angular 2 动态组件加载 ngOnChanges 生命周期钩子调用

初始化所有孩子后的Angular 2生命周期钩子?

react中的生命周期钩子函数

角度实际上是如何触发生命周期钩子的?