When I was doing an Angular change detection experiment, I discovered an interesting phenomenon。

46 Views Asked by At

Q1:When I try to trigger the add() method using DOM events,DOM events in runOutsideAngular, and Rxjs at the same time, the ordinary DOM event does not take effect.

Q2: why can I detect changes correctly even though I am not in ngZone when I just use the add() method? Is this because of Angular's one-way data flow?

the template:

      <h2 class="card-title text-white">{{ number }}</h2>
      <div class="card-actions justify-end">
        <!-- (click)="updateTitle()" -->
        <button class="btn btn-warning" (click)="add()">ADD</button>
        <button class="btn btn-warning" #addBtn>
          ADD
        </button>
      </div>

the part of logic:

  add() {
    this.ngZone.runOutsideAngular(() => {
      this.number++;
      console.log('isInAngularZone: ', NgZone.isInAngularZone());
      console.log(' Add:', this.number);
    });
  }

  ngAfterViewInit(): void {
    (this.addBtn.nativeElement as HTMLButtonElement).onclick = () => {
      this.number++;
      console.log('DOM:', this.number);
    };

    this.ngZone.runOutsideAngular(() => {
      (this.addBtn.nativeElement as HTMLButtonElement).onclick = () => {
        this.number++;
        // this.cdr.detectChanges();
        this.cdr.markForCheck();
        this.appRef.tick();
        console.log('tick:', this.number);
      };
    });

    fromEvent(this.addBtn.nativeElement as HTMLButtonElement, 'click')
    .subscribe(() => {
      this.number++;
      console.log('RxJS:', this.number);
    });
  }

the result in console:

tick: 2
RxJS: 3
tick: 4
RxJS: 5
tick: 6
RxJS: 7
tick: 8
RxJS: 9
tick: 10
RxJS: 11

I tried commenting out part of the code to see the results, but this seems to be caused by the internals of Angular's change detection mechanism.

0

There are 0 best solutions below