2017-07-31 50 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個通話

作爲角度帶