简体   繁体   中英

Why does Angular produce 3 rather than 1 in the following simple code?

Why is the output 3 rather than 1 in the following code?

app.component.ts :

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {

   i: number =0;  

  get count(): number{
    this.i++;
    return this.i;
  }
}

app.component.html :

<h1>{{count}}</h1>

The rendered output on the browser is 3 .

This is because TypeScript is compiled into javascript, and in js there is no notion of "getter" - there are objects and functions.

So, what you're doing is using a function in a template. And since angular can't know what could change the value returned by the function, it's evaluated on every change detection cycle that affects the component. So, in your case - there were 3 change detection cycles ran before your app fully rendered.

Caveat is - don't use functions to bind values in templates unless you're using the OnPush change detection strategy (and even then double-think if you REALLY need to use a function and are aware of possible 'gotchas').

On a sidenote - using a getter with a side-effect affecting the returned value is probably a no-go in any language, but I assume it was only to illustrate your issue.

This is a larger question dealing with how Angular handles change detection.

If you update your component as follows(specifying the OnPush ChangeDetectionStrategy), then you will see the expected value of 1.

    import { Component, ChangeDetectionStrategy } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class AppComponent {
    
       i: number =0;  
    
      get count(): number{
        this.i++;
        return this.i;
      }
    }

You can read more about this enum and the related topics on Angular's docs:

Stackblitz example

It is because of Angular's Change Detection mechanism.

Multiple change detection cycles are performed, and for each of them the getter for the 'count' property is called.

Since the getter for the 'count' property contains the instruction to increment the value of property 'i', the value will be incremented at each change detection cycle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM