Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
710 views
in Technique[技术] by (71.8m points)

angular - In Angular2, why are there 2 times check for content and view after setTimeout?

Here's my code

@Component({
  template: `<h1>Hello from A</h1>
  <ul>
    <li *ngFor="#letter of letters; #i = index">
      <button (click)="appendW(i)">{{letter | uppercase}}</button>
    </li>
  </ul>
  <button (click)="doSomething()">Click</button>`,
  pipes: [UpperCasePipe],
  directives: [NgFor]
})
export class AComponent {
  letters = ['a','b','c','d'];
  contructor(){

  }

  appendW(index) {
    // console.log(letter);
    setTimeout(()=>{
      this.letters[index] += "W";
    }, 1000)
  }
  ...
}

Plnkr

After setTimeout, angular checks twice for content and view. Can somebody explain this? Why does angular need to check TWICE?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Angular utilizes zones to know when an event is fully processed by patching some async APIs like (addEventHandler, setTimeout, ...) and then runs change detection after each event.

In dev mode Angular does an additional change detection run, just after the first one. Because there was no event in between, no change should have happened.

If the model still changed, Angular considers this to be a possible bug.

Possible causes:

  • A field, getter or function the view binds to returns a different instance each time, which is recognized as change.
    This is often with functions that return a filtered subrange of an array. This subrange should be assigned to a field and return the same cached instance unless a filter criteria has changed.
    Angular only compares identity of the previously and currently returned array and ignores whether the content of the array (or other objects) is still the same.

  • Code that was invoked by an event that was not registered within Angulars patched zone caused a model change.
    This is usually caused by 3rd-party libraries that aren't initialized fronm within Angular. Either initialize them within Angular if possible, or notify Angular about the change (Triggering Angular2 change detection manually)

In production mode Angular just checks once and ignores possible side effects.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...