我知道作用域监视器和过滤器都是在脏检查循环中重复执行的。但以下内容对我有点不清楚:
它们执行的循环次数相同吗?
它们都是由相同的情况触发的吗?
我知道作用域监视器和过滤器都是在脏检查循环中重复执行的。但以下内容对我有点不清楚:
它们执行的循环次数相同吗?
它们都是由相同的情况触发的吗?
$watch
可以观察Angular 表达式。在一个表达式中,可以有一个过滤器,Angular 必须评估它(使用$interpolate
)以确定观察的表达式是否已更改。$digest
运行的,而是作为$watch
评估表达式的结果运行的。实际上,过滤器是通过评估所观察的表达式来触发的。$digest
性能问题,过滤器有几个特殊的原因需要讨论。看一下这两个表达式:{{searchText+2}}
表达式2:{{searchText | myFilter:true}}
每次触发$digest
时,两个表达式都将被评估。因此,一个风险领域就是myFilter
可能会很复杂,并且最终使用比某些简单内容(如上面的+2)更多的处理器周期。$digest
运行时,如果任何监视结果发生更改,则会设置一个脏标志。并且如果设置了该脏位,则会重新运行所有监视器。这允许传播任何更改。例如,如果其中一个监视器更改了searchText
,则Angular需要让所有其他监视器有机会查看它们的结果是否取决于searchText
,从而应发生更改。myFilter
返回一个随机数。当评估观察器时(过滤器的先前结果与新结果不匹配),$digest
运行并检测到更改,因此它再次运行观察列表。由于过滤器返回一个随机数,其结果很可能已经改变,从而触发了$digest
的另一次运行等等... Angular在遍历其观察列表10次后内置停止-如果结果在10次尝试后不稳定,则认为出现问题,因此放弃并抛出“错误:达到10个$digest()迭代。中止!”
它们执行相同数量的周期吗?
因此,每个观察表达式(包括任何过滤器)至少在每个$digest
中运行两次。一次是因为触发了$digest
的更改,另一次是为了检查该结果是否需要传播。如果该传播导致任何更改,则会重新运行观察器和过滤器,直到没有任何变化。
当然,如果多个观察表达式使用同一个过滤器,则该过滤器将按照上述方式为每个表达式运行。