我有一个执行以下操作的指令:
$compile()
以使AngularJS重新编译元素,以便附加新指令。这样可以正常工作,除非我还在元素中添加了ng-if。请参阅此最小示例,并按照以下步骤进行演示。
https://embed.plnkr.co/ymk0RwGopGF1KvesWmvA/
+
任意次,即可添加到"计算"。0
重置"计算"。+
任意次。我希望&#34; my-test显示&#34; <p>
标记在步骤#2后ng-if
条件不再为真时从DOM中删除。相反,它会保持不变,并且您会在步骤#3之后看到该消息的额外副本。
我假设在my-test指令链接函数中调用$compile($element)($scope);
会产生一些意想不到的后果,但我不明白这里发生了什么。有什么想法吗?
谢谢, 大卫
答案 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):
主/外部控制器有scope[2]
ng-if my-test
元素ng-if
查看scope[2].count
并创建scope[3]
my-test
个链接器有$scope.$id == 3;
my-test
执行$compile
- 重新编译ng-if
元素:创建新隔离scope[4]
并正在查看scope[3].count
当scope[2].count
点击0时,scope[3]
获得$destroyed
(因为scope[3]
是由第一个ng-if
创建的,而$compiled
仍在某处徘徊......但是!元素是A.仍然在那里B.它的计数没有更新 - 为什么?
好吧,因为仍然存在的那个元素是ng-if
并且有A. scope[3].count
看scope[4]
(现在是$ destroy)和B.它自己的新元素隔离ng-if
(通过使用父scope[3]
重新编译$element.removeAttr('ng-if');
元素创建)
所以,你好。这一切都非常令人困惑,你可能只是在问......我该如何解决这个问题?
<强> TL; DR; 强>
最简单的解决方案:
在$compile($element)($scope);
ng-if
如果你一直在跟进,这是有效的,因为原始的scope[2].count
仍在查看new ObjectId()
,并且存在的元素不再是第二个隔离范围。