当我在 angular 中递增此数字输入时,为什么会调用此模板中的其余方法?

Why do the rest of methods in this template get called when I increment this number input in angular?

如果你看一下这个 stackblitz 代码:https://stackblitz.com/edit/angular-ivy-xvxgrhrecipie-ingredients 模块的文件 recipie-ingredients.component 的第 7 行,您可以看到我输入了一个数字。这意味着每次我增加调用 modifyPeopleCount 方法的输入数字的值。但是,当我增加该输入数字时,该 angular 模板中的其余方法也会被调用。例如 adjustIngredientAmount 也被称为。在 angular 中如何调用此功能?为什么不只调用 modifyPeopleCount 方法?

这是因为Angular的"change detection"。

假设在 HTML 模板中你有这个:

<b> {{ adjustIngredientAmount(entry) }}</b>

所以应该显示的值是带有参数 entry 的函数 adjustIngredientAmount 的结果。但是编程语言可以知道函数结果的唯一合乎逻辑的方法是 call/execute 它。

想一想这个函数就好像是一个完整的黑盒子,你无法深入研究它。所以你必须执行它才能获得价值。

Angular有"change detection"运行(不会link文章那么多,找适合自己看的就好)有点"smart" 猜测函数的结果何时可能发生变化。

所以基本上:无论您在模板中使用什么功能来显示事物(或者如果在 ngIfngFor 等中使用)angular 将在任何时候执行这些功能 "something" 发生变化,因为函数的结果可能会有所不同。

"something" 不是那么容易解释的,所以只要阅读有关它的文章即可。您还可以更改 angular 用于评估何时可能发生变化的策略。

此外,还有一些方法可以手动 "tell" angular 某些内容已更改。

并不是 "wrong" 函数是这样调用的,但是如果您的应用增长,您应该考虑避免在 html 内部调用函数的模式,因为这些调用以后可能会呈指数级增长 :)


编辑: 添加我在其他答案下评论的内容:

一种解决方案可能是 OP 在创建数组时计算这些值,并将这些计算值作为一些元数据添加到数组中。然后他可以直接访问它们。但这始终是一种权衡。模板内的函数可以节省内存但会消耗执行力。另一种方式消耗内存但节省执行力。

Angular 将在更改检测周期内重新计算整个模板。看起来 modifyPeopleCount 也改变了 servingRatio,这是 adjustIngredientAmount 计算的一部分。为什么不应该也更新这些值? Angular 认为他们应该这样做。真的,没有办法知道模板中的哪些函数调用不需要作为调用 modifyPeopleCount 的结果。 Angular 将检查组件是否发生变化,并在此过程中将重新计算整个模板,同时还会调用 html.

中编写的函数和 getter

为避免 Angular 在模板上重新计算值,您可以将计算值构造为 RecipeEntry 上的字段的对象,并在其他事件的其他地方重新计算它们。