简体   繁体   English

生命周期挂钩方法中的Angular2更改检测

[英]Angular2 change detection in lifecycle hook methods

I want to show a spinner in ngOnInit() and hide it in ngAfterViewInit(). 我想在ngOnInit()中显示一个微调框,然后在ngAfterViewInit()中将其隐藏。 But this is not working: 但这不起作用:

  • without setTimeout(), nothing happen 没有setTimeout(),什么都不会发生
  • with setTimeOut(), the spinner show and hide (blink), but after ngAfterViewInit() 使用setTimeOut(),微调器显示和隐藏(闪烁),但在ngAfterViewInit()之后

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

In this example the spinner component (spinner.ts) is a div tag that changes background color. 在此示例中,微调器组件(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}`);
        }
    }
}

On clic on 'link to my component' (mycomponent.ts), I want the background color spinner is red between ngOnInit() and ngAfterViewInit(). 关于“链接到我的组件”(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');
  }

}

What is the solution? 解决办法是什么?


UPDATE UPDATE

I update the sample http://plnkr.co/edit/M1g7DT1Eks2gtuSXi1B1?p=preview to use observable. 我将示例http://plnkr.co/edit/M1g7DT1Eks2gtuSXi1B1?p=preview更新为使用可观察的。

I set the spinner to show in ngOnInit() but ngOnChanges() of the spinner component is called after ngAfterViewInit() 我将微调器设置为在ngOnInit()中显示,但是微调器组件的ngOnChanges()在ngAfterViewInit()之后调用

The log console is : 日志控制台是:

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**

So it seems that there is no immediately change detection in lifecycle hook methods? 因此,似乎在生命周期挂钩方法中没有立即进行更改检测? Right or wrong? 对还是错?

To achieve this, I think it's better put directly the spinner as non-angular component inside the <my-app> tags. 为此,我认为最好将微调框作为非角度组件直接放在<my-app>标记内。 In this way, you can obtain a spinner that display until the application is fully loaded. 这样,您可以获得在应用程序完全加载之前一直显示的微调器。

If you try to achieve this using angular components, the spinner does not show until the angular app is loaded, and when it is loaded the spinner at that moment is useless. 如果尝试使用角度组件来实现此目的,则直到加载了角度应用程序后,微调器才会显示,并且当加载了角度应用程序时,此时微调器是无用的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM