35494

[code]

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      // templateUrl: './app.component.html',
      template:`
          <div *ngFor="let v of getArray();">
            {{v}}
          </div>
      `,
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      getArray(){
        console.log("getArray");
        return [1,2,3,5,6];
      }
    }
    
[/code]

上記を実行するとlogに  
11:17:30.567 app.component.ts:15 getArray  
11:17:30.578 app.component.ts:15 getArray  
11:17:30.579 lang.js:130 Angular is running in the development mode. Call
enableProdMode() to enable the production mode.  
11:17:30.581 app.component.ts:15 getArray  
11:17:30.582 app.component.ts:15 getArray

と表示されます。なぜ4回も実行されるのでしょうか？


CC BY-SA 3.0
2017-06-10T02:20:04.980
35449
2017-06-12T02:17:19.697
8823
question
angular2 angular4
AngularのngForが４回実行される。


Angular、またはAngularJSは変更検知の仕組みによりデータバインディングを実現しています。  
コンポーネントに関数を渡すと変更検知のために呼び出されます。  
(関数を評価しないと変更があるかどうかをAngularが判断できない)

変更検知は様々なタイミングで行われるため、複数回呼び出されています。  
変更検知について詳しく知りたければ、Angularjsであれば$digestイベントループを、Angularであれば[ZoneJSによる変更検知の仕組み](https://blog.thoughtram.io/angular/2016/02/01/zones-
in-angular-2.html)などについて調べると良いかと思います。

変更検知の仕組みがあるのでngFor(コンポーネント)に関数を渡す実装はパフォーマンスの面であまり良くはありません。  
コンポーネントのオブジェクトとしてデータバインディング用の変数を定義し、それをngForに渡すようにしてください。

[code]

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      // templateUrl: './app.component.html',
      template:`
          <div *ngFor="let v of arrays">
            {{v}}
          </div>
      `,
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      numArray: Array<Number>;
    
      ngOnInit() {
        this.numArray = this.getArray();
      }
    
      getArray(){
        console.log("getArray");
        return [1,2,3,5,6];
      }
    }
    
[/code]


CC BY-SA 3.0
2017-06-12T02:17:19.697
35494
2017-06-12T02:17:19.697
20272
35449
answer