我有一个简单的数据表,使用AngularJS创建。表中的一列是根据控制器上的函数计算的。
我在页面上有一个按钮,可以打开一个新模态。当我使用UI引导打开模态时,我得到一个新的孤立范围(根范围的子),如预期的那样。但是,如果我在模态中有输入文本,则此文本字段中的任何按键都会自动调用父作用域上的函数 - 即使我可以验证作用域是否已隔离。
以下是行为的一部分:http://plnkr.co/edit/JzhxSDcSefDe04Psxq0w
如示例所示,表的第三列是使用名为“ageNextYear”的函数计算的。在呈现表时,会按预期多次调用此函数(并且可以在控制台日志中进行验证)。但是,如果我打开模态并在字段中键入一些文本,则仍会调用父作用域上的“ageNextYear”函数(在输入字段中键入一些文本并观察控制台日志输出)。
我不确定这是否是预期的行为,或者我是否做错了什么。我尝试在两个作用域上使用点表示法,并明确地将新作用域传递给$ modal.open,但没有任何乐趣。
我可以解决这个问题(通过在“人员”上创建一个watchCollection并以这种方式更新表格 - 这可能是一种更好的方式来做到这一点)但是想验证其他人是否也看到了这种行为。
答案 0 :(得分:3)
您遇到的问题与模态对话框的范围无关。该问题与在ng-repeat表达式中使用函数有关。通常,在表达式中使用函数是一个性能问题,但它在ng-repeat中是一个更大的问题。根据这篇关于common pitfalls of using scopes,
的优秀文章在视图或观察者中使用表达式时,您应该始终记住每次AngularJS认为需要时都会调用表达式。使用函数不会获得最佳性能,甚至可能会错过一些更改事件。
这意味着表达......
将分别为每个项目调用ng-repeat内的
- 。此外,repeat指令使用它来确定数据更改。
- 可以在一个摘要中多次评估。当您使用多个指令或其他范围观察者时,可能会发生这种情况。
- 即使直接范围似乎没有变化,也可以进行评估。
- 如果函数的返回值发生更改,则不会计算包含函数,但仅在函数定义发生更改时才会计算。
醇>
您的示例会导致其中3个发生。
在您的情况下,每次计算表达式时都不需要运行逻辑。当逻辑结果发生变化时,最好计算逻辑并将其写入范围。这将逻辑与对象和视图分离。
总结,
最佳做法:
- 请勿在表达式中使用函数。
- 请勿在表达式中使用范围之外的其他数据。
- 在应用外部数据更改时,请使用$ scope。$ apply()。
答案 1 :(得分:1)
西蒙 我喜欢你的问题,我在范围上添加了监视,并看到了摘要周期被称为
$ scope。$ watch(功能watchMe(范围){console.log('摘要看着我!');});
以下是带摘要的fork。 http://plnkr.co/edit/5PTO1uPFvmLrg7K9vzTm?p=preview
我不知道这是原因,但我认为ng-repeat中的表达式正在调用摘要,因为它试图评估该项目上任何事件的表达式。
我认为我们应该评估模型中的表达式,并将更新的模型提供给ng-repeat以解决问题。