背景
我为当前项目创建了一个简单的指令,基本上在导航栏中创建一个简单的嵌套列表(单击以展开更多选项,再次单击关闭)。这个想法是为了消除每次使用其中一个时必须编写设置代码的所有开销,并让指令通过查找结构件,添加必要的角度属性,然后重新注入它们来重新编译所有角度组件。容器。
问题
在IE(而不是Edge)中,我发现列表根本不会呈现,经过大量调试后,我的问题缩小到$ compile。基本上,在操作元素之后,通过$ compile运行它们会破坏标记内的所有内容。我写了一个基本的例子。我在IE 11中使用它测试并得到了描述的行为。
http://codepen.io/DAquilina/pen/PWRzjB
问题区域
var injection = $(element).find ('> div');
$(injection).attr ('ng-if', 'true');
$(element).html ('');
$(element).append ($compile (injection) ($scope));
问题
我的问题分为两部分:
1)我所描述的问题是因为我推测的原因而发生的,还是我错过了其他的东西?
2)在保持上述代码抽象级别的同时,我还能做些什么来规避这个问题呢?
回复:I'm pretty sure you can supply the template for a directive via a function. Why are you doing it this way instead? Also, what happens if you don't set the html for the element to an empty string?
每次都不是相同的内容。在我的下拉列表中,您可能会遇到以下情况:
<li util-dropdown>
<a href>
Services
</a>
<ul>
<li>
<a href="/foo>Foo</a>
</li>
<li>
<a href="/bar">Bar</a>
</li>
</ul>
这将编译成:
<li util-dropdown class="util-dropdown">
<a href ng-click="utilDropdownToggle ()">
Services
</a>
<ul util-slide-transition-helper ng-if="!!utilDropDownExpanded">
<li>
<a href="/foo>Foo</a>
</li>
<li>
<a href="/bar">Bar</a>
</li>
</ul>
所以,是的,每次写入都不是很多额外的东西,但我宁愿HTML干净而不是。至于你问题的第二部分,这可能会解决我的问题,虽然我不确定为什么。调查它。
更新:笔已使用建议的用例进行更新,并且在所有浏览器中均可正常使用。如果有人能够在深层次的技术层面上解释这种行为,我将非常感激。
答案 0 :(得分:0)
如上所述,由于@Amy Blackenship的有用建议,找到了解决方案。
原始问题代码
var injection = $(element).find ('> div');
$(injection).attr ('ng-if', 'true');
$(element).html ('');
$(element).append ($compile (injection) ($scope));
更新代码
var injection = $(element).find ('> div');
$(injection).attr ('ng-if', 'true');
$compile (injection) ($scope);
那么改变了什么?
我对$ compile的工作原理有了新的认识,即元素内联而非本地化。这意味着在给定范围内运行$ compile不会克隆并返回操作的结果,而是更改操作之前存在的引用元素。在我上面的例子中,我选择了一个已经存在于页面上的元素,所以当我清除HTML时,它会在DOM中被销毁,而对它的引用仍然存在于我的代码中,以及它的时候。在那里重新注入IE并不真正知道如何纠正的冲突。在没有DOM操作步骤的情况下直接在元素上运行$ compile会绕过这种冲突。
对于笔中的示例1和2,操作的元素从不在页面上开始,因此引用已经是本地的,因此当它被注入时不存在冲突这页纸。事实上,我可以在编译步骤之前注入它,它仍然可以工作。
注意:如果在类似情况下进行调试,我在测试期间注意到的一件事是,如果我在调用$ compile之前为目标元素包含了一些日志语句,那么输出仍然包含后编译的元素,真的让我失望。