AngularJS ng-if如果不在$ compile之后删除元素

时间:2016-09-20 18:41:43

标签: angularjs angularjs-directive angularjs-compile

我有一个执行以下操作的指令:

  1. 向元素添加另一个指令属性。
  2. 删除自己的属性。
  3. 在元素上调用$compile()以使AngularJS重新编译元素,以便附加新指令。
  4. 这样可以正常工作,除非我还在元素中添加了ng-if。请参阅此最小示例,并按照以下步骤进行演示。

    https://embed.plnkr.co/ymk0RwGopGF1KvesWmvA/

    1. +任意次,即可添加到"计算"。
    2. 0重置"计算"。
    3. 再次按+任意次。
    4. 我希望&#34; my-test显示&#34; <p>标记在步骤#2后ng-if条件不再为真时从DOM中删除。相反,它会保持不变,并且您会在步骤#3之后看到该消息的额外副本。

      我假设在my-test指令链接函数中调用$compile($element)($scope);会产生一些意想不到的后果,但我不明白这里发生了什么。有什么想法吗?

      谢谢, 大卫

3 个答案:

答案 0 :(得分:2)

据我所知,当你用0更改count的值时,你的指令会在更改count的值之前被销毁。因此,未删除指令的计数值仍为1。

如果使用ngShow而不是ngIf,则可以解决此问题。因为ngShow属性不会触发$ destroy事件,也不会从视图中删除元素。因此该指令可以捕获count的新值。或者,您可以使用prelink代替link来更新count的值。

答案 1 :(得分:1)

我不知道如何正确解释但是ng-if为元素添加了一个新范围,他自己的范围,请检查这个问题以查看更多详细信息:what is the difference between ng-if and ng-show/ng-hide。我尝试使用ng-show,它按照你想要的方式工作:

ng-show="count > 0"

希望有帮助=)

答案 2 :(得分:1)

正如其他人所回答的那样,简短的解决方案是使用ng-show代替ng-if或不使用$compile。除此之外,您可能有充分的理由说明为什么要这样使用ng-if$compile

这个问题让我感兴趣的是$compile使用ng-if的隔离范围。我做了一些this fork的实验,并试图解释我发现的内容。

我们已经知道ng-if创建了一个隔离范围,但是通过ng-if$compile上的元素传递给它创建另一个隔离范围(并且会使新编译的ng-if正在查看第一轮隔离范围的变量 - 指令的$scope值。

为了重新迭代它,我们有一些范围看起来像([]中的值是范围。$ id):

  1. 主/外部控制器有scope[2]

  2. ng-if my-test元素ng-if查看scope[2].count并创建scope[3]

  3. 因此,
  4. my-test个链接器有$scope.$id == 3;

  5. my-test执行$compile - 重新编译ng-if元素:创建新隔离scope[4]并正在查看scope[3].count

  6. scope[2].count点击0时,scope[3]获得$destroyed(因为scope[3]是由第一个ng-if创建的,而$compiled仍在某处徘徊......但是!元素是A.仍然在那里B.它的计数没有更新 - 为什么?

  7. 好吧,因为仍然存在的那个元素是ng-if并且有A. scope[3].countscope[4](现在是$ destroy)和B.它自己的新元素隔离ng-if(通过使用父scope[3]重新编译$element.removeAttr('ng-if');元素创建)

    所以,你好。这一切都非常令人困惑,你可能只是在问......我该如何解决这个问题?

    <强> TL; DR;

    最简单的解决方案: 在$compile($element)($scope);

    之前ng-if

    如果你一直在跟进,这是有效的,因为原始的scope[2].count仍在查看new ObjectId(),并且存在的元素不再是第二个隔离范围。