假设我有一个大数组的ng-repeat。
当ng-repeat运行时,它会将数组的每个元素添加到一个独立的作用域中,同时将数组本身也包含在一个作用域中,这意味着$digest会检查整个数组的变化,并且在此基础上,它会检查数组中的 * 每个元素 * 的变化。
请将this plunker作为我所讨论的内容的示例。
在我的用例中,我从不更改数组中的任何一个元素,所以我不需要监视它们。我只会更改整个数组,在这种情况下,ng-repeat将重新呈现整个表。(如果我错了,请告诉我。)
在一个1000行的数组中,还有1000个表达式不需要计算。
如何在监视主数组的同时从监视器注销每个元素?
也许我可以更好地控制我的$digest并跳过每一行,而不是注销?
这个具体的例子实际上是一个更普遍的问题的例子,我知道$watch returns a 'deregisteration' function,但当一个指令注册手表时,这是没有帮助的,这是大多数时候。
5条答案
按热度按时间wlsrxk511#
您需要创建一个自定义指令,该指令将一个参数和表达式添加到数组中,然后在链接函数中,您只需查看该数组,并让链接函数以编程方式刷新HTML(而不是使用ng-repeat)
类似于(伪代码):
......这看起来像是个麻烦。
你可以循环
$scope.$$watchers
,检查$scope.$$watchers[0].exp.exp
是否匹配你想要删除的表达式,然后用一个简单的splice()
调用来删除它。这里的PITA是,像Blah {{whatever}} Blah
这样的标签之间的东西将是表达式,甚至包括回车符。从好的方面来说,你可以在ng-repeat的$作用域中循环,删除所有内容,然后显式地添加你想要的手表......我不知道。
不管怎样,这看起来像是黑客。
可以使用
$watch
调用返回的函数注销$watch
:例如,要使
$watch
仅激发一次:当然,您可以随时调用unregister函数......这只是一个示例。
但有一点要考虑:这值得担心吗?此外,将数千条记录加载到数十个DOMELENTS中真的是一个好主意吗?值得思考。
2wnc66cl2#
$watch返回一个函数,在调用时解除$watch的绑定。因此,这就是“watchOnce”所需的全部内容:
4nkexdtk3#
编辑:看我贴出的另一个答案。
我已经用一种独立的方式实现了blesh的想法,我的
ngOnce
指令只是破坏了ngRepeat
在每个项目上创建的子作用域,这意味着该作用域不能从其父作用域的scope.$digest
中访问,监视器也永远不会执行。Source and example on JSFiddle
指令本身:
使用它:
ng-once
不创建自己的作用域,这意味着它可以影响兄弟元素。这些都做同样的事情:hjqgdpho4#
您可以将
bindonce
指令添加到您的ng-repeat
中。您需要从https://github.com/pasvaz/bindonce下载它。edit:一些警告:
如果在模板中使用
{{}}
插值,则需要将其替换为<span bo-text>
。如果您使用的是
ng-
指令,则需要将其替换为正确的bo-
指令。此外,如果要将
bindonce
和ng-repeat
放在同一个元素上,则应该尝试将bindonce
移动到父元素(参见https://github.com/Pasvaz/bindonce/issues/25#issuecomment-25457970),或者将track by
添加到ng-repeat
。llycmphe5#
如果您使用的是
angularjs 1.3
或更高版本,则可以使用单绑定语法,如这将绑定该值,并在运行第一个摘要周期且该值第一次从
undefined
更改为defined
时删除监视器。这是一个非常有用的BLOG。