2017-07-31 32 views
2

我知道,如果我们在发展角度运行变化检测两次。在以下示例中,Angular运行更改四次检测。这是为什么发生?角度变化检测运行八倍而不是四个

class Category { 
    constructor(private _id) { 
    } 

    get id() { 
    console.log('id'); 
    return this._id; 
    } 

} 

@Component({ 
    selector: 'app-select', 
    template: ` 
     <select class="form-control"> 
     <option *ngFor="let option of options;" [value]="option.id">{{option.id}}</option> 
     </select> 
    `, 
}) 
export class SelectComponent { 
    @Input() options; 
} 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <app-select [options]="options"></app-select> 
    `, 
}) 
export class App { 
    options = [new Category(1)] 
} 

@NgModule({ 
    imports: [ BrowserModule ], 
    declarations: [ App, SelectComponent ], 
    bootstrap: [ App ] 
}) 
export class AppModule {} 

如果您运行上面的代码,您将看到控制台日志运行八次而不是四次。

+0

变化检测运行多次第一次启动时,角度运行'app.tick'两次 –

+0

需要每个异步任务 – yurzui

+0

所以它应该console.log四次,而不是八次。 – ng2user

回答

7

我知道这是不是证明,但角运行额外appRef.tick的Bootstrap应用程序时

private _loadComponent(componentRef: ComponentRef<any>): void { 
    this.attachView(componentRef.hostView); 
    this.tick(); 

https://github.com/angular/angular/blob/4.3.x/packages/core/src/application_ref.ts#L540

然后调用主处理器运行变化检测

this._zone.onMicrotaskEmpty.subscribe(
    {next:() => { this._zone.run(() => { this.tick(); }); }}); 

https://github.com/angular/angular/blob/4.3.x/packages/core/src/application_ref.ts#L445

tick方法角度运行detectChanges方法

this._views.forEach((view) => view.detectChanges()); 

https://github.com/angular/angular/blob/master/packages/core/src/application_ref.ts#L561

和DEV方式changeNoChanges

if (this._enforceNoNewChanges) { 
    this._views.forEach((view) => view.checkNoChanges()); 
} 

https://github.com/angular/angular/blob/master/packages/core/src/application_ref.ts#L563

所以角运行更改第一初始化检测4次。

由于您使用的模板的getter两次

[value]="option.id">{{option.id}} 

将被执行两次,最后你会得到8个通话

作为角度带