简体   繁体   English

为什么 Angular 在以下简单代码中产生 3 而不是 1?

[英]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?为什么以下代码中的 output 是 3 而不是 1?

app.component.ts : 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 : app.component.html

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

The rendered output on the browser is 3 .在浏览器上呈现的 output 是3

This is because TypeScript is compiled into javascript, and in js there is no notion of "getter" - there are objects and functions.这是因为TypeScript被编译成javascript,而在js中没有“getter”的概念——有对象有函数。

So, what you're doing is using a function in a template.因此,您正在做的是在模板中使用 function。 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.由于 angular 不知道什么可以更改 function 返回的值,因此在影响组件的每个更改检测周期对其进行评估。 So, in your case - there were 3 change detection cycles ran before your app fully rendered.因此,在您的情况下 - 在您的应用程序完全呈现之前运行了 3 个更改检测周期。

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').警告是——不要使用函数来绑定模板中的值,除非你使用 OnPush 更改检测策略(即使你真的需要使用 function 并且意识到可能的“陷阱”,也要仔细考虑)。

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.这是一个更大的问题,涉及 Angular 如何处理变化检测。

If you update your component as follows(specifying the OnPush ChangeDetectionStrategy), then you will see the expected value of 1.如果您按如下方式更新您的组件(指定 OnPush ChangeDetectionStrategy),那么您将看到预期值 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:您可以在 Angular 的文档中阅读有关此枚举和相关主题的更多信息:

Stackblitz example Stackblitz 示例

It is because of Angular's Change Detection mechanism.这是因为 Angular 的变更检测机制。

Multiple change detection cycles are performed, and for each of them the getter for the 'count' property is called.执行多个更改检测循环,并为每个循环调用“count”属性的 getter。

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.由于“count”属性的 getter 包含递增属性“i”值的指令,因此该值将在每个更改检测周期递增。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么这段代码在JavaScript中产生3? - Why does this code produce 3 in JavaScript? 为什么新的expo init会产生“导出默认功能”而不是“导出默认类”? 在App.js中 - Why does a new expo init produce “export default function” rather than “export default class”? in App.js 为什么我的代码落后 2 个刻度(而不是 1 个)? - Why is my code is 2 ticks behind (rather than 1)? 为什么结果数组以 0 而不是 1 开头? - Why does the result array start with 0 rather than 1? 为什么我的代码没有产生预期的结果? 它打印的比我想要的多 - Why does my code not produce the expected result? It prints more than what I want 为什么以下javascript代码段会生成一个空的zip存档? - Why does the following javascript snippet produce an empty zip archive? 为什么以下map函数产生未定义的对象? - Why does the following map function produce undefined objects? "为什么 a show &quot;function getFullYear() { [native code for Date.getFullYear, arity=0] }&quot; 而不是方法返回的值?" - why does a show "function getFullYear() { [native code for Date.getFullYear, arity=0] }" rather than the value returned by the method? 为什么这段代码必须使用 Math.min.apply 而不仅仅是 Math.min - Why does this code excert have to use Math.min.apply rather than just Math.min 从Babel AST生成ES6代码而不是ES5代码 - Produce ES6 code rather than ES5 code from Babel AST
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM