Javascript $compile剥离IE中被操纵标记的内部内容

Javascript $compile剥离IE中被操纵标记的内部内容,javascript,angularjs,Javascript,Angularjs,背景 我为当前项目创建了一个简单指令,基本上是在导航栏中创建一个简单的嵌套列表(单击以展开更多选项,再次单击以关闭)。其想法是消除每次使用其中一个组件时都必须编写设置代码的所有开销,并通过查找结构块、添加必要的角度属性,然后将它们重新注入容器,让指令使用所有角度组件重新编译自身 问题 在IE(不是Edge)中,我发现列表根本不会呈现,经过大量调试后,我的问题缩小到$compile。基本上,在操作元素之后,通过$compile运行它们会破坏标记中的所有内容。我已经写了一个基本的例子。我在IE 11

背景

我为当前项目创建了一个简单指令,基本上是在导航栏中创建一个简单的嵌套列表(单击以展开更多选项,再次单击以关闭)。其想法是消除每次使用其中一个组件时都必须编写设置代码的所有开销,并通过查找结构块、添加必要的角度属性,然后将它们重新注入容器,让指令使用所有角度组件重新编译自身

问题

在IE(不是Edge)中,我发现列表根本不会呈现,经过大量调试后,我的问题缩小到$compile。基本上,在操作元素之后,通过$compile运行它们会破坏标记中的所有内容。我已经写了一个基本的例子。我在IE 11中使用它进行了测试,得到了描述的行为

问题领域

问题

我的问题分为两部分:

1) 我所描述的问题是因为我猜测的原因而发生的,还是我遗漏了什么

2) 在保持上述代码抽象级别的同时,我可以做些什么来避免这个问题



Re:
我很确定您可以通过函数为指令提供模板。你为什么要这样做?另外,如果不将元素的html设置为空字符串,会发生什么情况?

每次的内容都不一样。在我的下拉列表中,您可能有以下内容:

<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是干净的,而不是没有。至于你问题的第二部分,这可能会解决我的问题,尽管我不知道为什么。调查一下


    更新:Pen已使用建议的用例进行了更新,在所有浏览器中都能正常工作。如果有人能从深层次的技术层面上解释这种行为,我将不胜感激。

    如上所述,多亏了

    原始问题代码

    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);
    
    更新代码

    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不知道如何纠正的冲突。直接在元素上运行$compile而不执行DOM操作步骤可以绕过此冲突

    在钢笔中的示例1和示例2中,被操纵的元素从来都不在页面上,因此引用已经是本地的,因此在注入页面时不存在冲突。事实上,我可以在编译步骤之前注入它,它仍然可以工作


    注意:如果在类似的情况下进行调试,我在测试中注意到的一点是,如果在调用$compile之前为目标元素包含一些日志语句,那么输出仍然包含post-compiled元素,这真的让我大吃一惊。

    我很确定您可以通过函数为指令提供模板。你为什么要这样做?此外,如果不将元素的html设置为空字符串,会发生什么情况?上面回答。我有一些研究要做,很有效!如果你回答这个问题,我会接受的。我这样做了,我删除了追加操作,因为它实际上什么都没有做。我认为你应该写下答案,因为你知道你做了什么以及为什么它会起作用。