如何在 AngularJS 摘要循环中处理观察者和过滤器



我知道范围观察器和过滤器都在摘要循环中重复执行。但是,以下内容对我来说有点不清楚:

  • 它们执行的周期数是否相同?

  • 两者都是由相同的情况触发的吗?

手表在每个

摘要周期进行检查。 $watch可以观看 Angular 表达式。 在表达式中可以有一个过滤器,Angular 必须对其进行评估(使用 $interpolate )来决定监视的表达式是否已更改。

两者都是由相同的情况触发的吗?

因此,过滤器不是由$digest直接运行的,而是作为$watch的结果运行的。 实际上,筛选器是由监视表达式的评估触发的。

有几个原因 过滤器被特别谈论 关于$digest的性能 . 看看这两个表达式:

表情一:{{searchText+2}}

表情二:{{searchText | myFilter:true}}

每次触发$digest时,都会计算这两个表达式。 因此,一个风险领域很简单,myFilter可能很复杂,最终使用的处理器周期比简单的东西多得多(如上面的 +2)。

不太明显的是,如果筛选器不是幂等的,则可能会导致所有观察程序的额外运行。 在每次运行$digest时,如果任何监视导致更改,则会设置脏位。 如果设置了脏位,它会再次重新运行所有手表。 这允许传播任何更改。 例如,如果其中一个手表更改了searchText,那么 Angular 需要让所有其他观察者有机会查看他们的结果是否取决于searchText因此应该改变。

这就是上述表达式 1 和 2 之间的区别。 作为最坏的情况,假设myFilter返回一个随机数。 $digest运行,在评估监视时看到更改(筛选器的先前结果与新结果不匹配),因此它会再次运行监视列表。 由于过滤器返回一个随机数,因此其结果很可能已更改,从而触发了另一次$digest运行。等等等等...Angular 在通过其监视列表循环 10 次后有一个内置的停止 - 它会计算如果结果在 10 次尝试后没有稳定下来,那么出了问题,所以它放弃抛出"错误:达到了 10 次$digest()迭代。流产!

它们执行的周期数是否相同?

因此,每个监视的表达式(包括任何过滤器)至少每$digest运行两次。 一次是因为触发$digest的更改,再次检查该结果是否需要传播。 如果该传播导致任何更改,则监视和筛选器将再次运行,直到没有任何更改。

当然,如果多个监视的表达式使用相同的过滤器,那么将按照上述操作为每个表达式运行该过滤器。

最新更新