繁体   English   中英

在Angular + UI Bootstrap中创建隔离范围的问题

[英]Issue creating isolated scope in Angular + UI Bootstrap

我有一个使用AngularJS创建的简单数据表。 该表的其中一列是根据控制器上的函数计算的。

我在页面上有一个按钮,可以打开新的模式。 当我使用UI引导程序打开模式时,正如预期的那样,我得到一个新的隔离范围(根范围的子级)。 但是,如果我在模式中有输入文本,即使我可以确认范围是隔离的,此文本字段中的任何按键操作也会自动调用父作用域上的函数。

这是该行为的罪魁祸首: http ://plnkr.co/edit/JzhxSDcSefDe04Psxq0w

如示例中所示,该表的第三列是使用名为“ ageNextYear”的函数计算的。 呈现表时,此函数将按预期多次调用(并且可以在控制台日志中进行验证)。 但是,如果我打开模式窗口并在该字段中键入一些文本,则仍会调用父作用域上的“ ageNextYear”函数(在输入字段中键入一些文本并查看控制台日志输出)。

我不确定这是否是预期的行为,或者我做错了什么。 我尝试在两个作用域上都使用点表示法,并将新作用域显式传递给$ modal.open,但没有任何乐趣。

我可以解决这个问题(通过在“ people”上创建watchCollection并以这种方式更新表-这可能是整体上更好的方法),但想验证其他人是否也看到了此行为。

您遇到的问题与“模态对话框”的范围无关。 问题与ng-repeat表达式中函数的使用有关。 通常,在表达式中使用函数是一个性能问题,但是在ng-repeat中这是一个更大的问题。 根据这篇关于使用范围的常见陷阱的出色文章,

在视图或观察者中使用表达式时,您应始终记住,每当AngularJS认为需要表达式时,都会调用该表达式。 使用函数将无法获得最佳性能,甚至可能会错过一些更改事件。

那意味着一种表达……

  1. 在ng-repeat中将分别为每个项目调用。 此外,repeat指令使用它来确定数据更改。
  2. 可以在一个摘要中进行多次评估。 当您使用多个指令或其他作用域监视程序时,可能会发生这种情况。
  3. 即使直接作用域似乎没有变化,也可以进行评估。
  4. 如果函数的返回值发生更改,则仅在函数定义已更改的情况下,才会评估包含函数的内容。

您的示例导致这4个中的3个发生。

  1. 您对范围内的每个对象重复执行该函数调用,即3个项目= 3次对该函数的调用。
  2. 您可以通过调用“模态对话框”间接添加其他观察者。
  3. 即使ng-repeat中的数据没有更改(“ $$”也无法知道数据是否已更改,直到“ $$”更改了“模态对话框”范围中的数据后,才会评估包含ng-repeat的控制器的范围)摘要称为)。 对Modal的每次更改都会导致$ digest,这将导致ng-repeat的另一次行程,以及ng-repeat中每个项目的另一个调用。

在您的情况下,逻辑不必每次都将对表达式求值时运行。 逻辑结果更改后,最好将逻辑计算并写入范围。 这将逻辑与对象和视图分离。

综上所述,

最佳做法:

  • 不要在表达式中使用函数。
  • 除了表达式的范围外,请勿使用其他数据。
  • 应用外部数据更改时,请使用$ scope。$ apply()。

西蒙,我喜欢您的问题,并且在示波器上添加了监视功能,并看到摘要循环已被调用

$ scope。$ watch(function watchMe(scope){console.log('Digest看着我!');});

以下是带有摘要的分支。 http://plnkr.co/edit/5PTO1uPFvmLrg7K9vzTm?p=preview

我不知道这是原因,但是我认为ng-repeat中的表达式正在调用摘要,因为它试图评估该项目上任何事件的表达式。

我认为我们应该评估模型中的表达式,并将更新后的模型提供给ng-repeat来解决问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM