【问题标题】:How to dynamically nest a directive element in-between existing parent and child directive elements?如何在现有的父子指令元素之间动态嵌套指令元素?
【发布时间】:2014-08-20 06:09:54
【问题描述】:

背景:

我正在使用自定义 CMS,但我对代码库的访问权限有限。因此,在某些情况下,我计划使用 JavaScript 进行一些 DOM 操作。

问题:

我有一个容器指令,并且容器有普通的旧 HTML 项,但我无法将这些项标记为来自服务器端的指令。此外,普通的旧 HTML 项包含作为指令的子内容。

示例:

这是之前的:

DIV[container-directive]

  DIV.some-item-in-html
    DIV[some-directive-in-the-content]


  DIV.some-item-in-html
    DIV[some-directive-in-the-content]

  ...

这是 DOM 之后的样子:

DIV[container-directive]

  DIV[container-item]       <-- This is what needs to be inserted

    DIV.some-item-in-html
      DIV[some-directive-in-the-content]

  DIV[container-item]       <-- This is what needs to be inserted

    DIV.some-item-in-html
      DIV[some-directive-in-the-content]

  ...

问题:

是否有人对使用 JavaScript 在指令嵌套之间注入指令的 DOM 元素的最佳方法有建议?

一些想法:

我认为在编译之前通过 Angular 操作 DOM,但我想知道在 Angular 的框架内是否有办法做到这一点。

另一个选项来自容器指令的后链接功能,我可以将 HTML 项包装在称为“container-item”的指令元素中,然后手动 $compile 这些项。所以,我尝试了这个,但我得到了一个错误,它与内部已经包含指令的项目相关,并且包含了嵌入的内容。关于“ngTransclude”的一些事情是出乎意料的。我认为这与已经处理的内部指令有关。

【问题讨论】:

  • 建议您创建一个演示来复制问题和您尝试过的代码
  • 我知道你在问什么,但我并没有真正尝试修复损坏的代码。可能有几种方法可以解决上述问题。如果是这样,那么如果一个有效的解决方案非常不同,那么我的代码可能并不重要。另一方面,如果只有一种方法可以完成上述问题,那么我的代码也无关紧要,因为答案将具有可以在答案中编写的单一代码结构(大概使用相对较短的代码量),或者熟悉此事的人可以在不编写代码的情况下提出最佳方法,这将是一个有效的答案。
  • 这种方法并不适合这个网站,你提到你尝试了一些不起作用的东西,所以发布那个代码。这通常是这里的工作方式

标签: javascript html angularjs dom angular-directive


【解决方案1】:

我会选择您的第一个选项,并在 Angular 编译之前操作 DOM。

您可以在包含您要操作的元素的指令中执行此操作。

例如:

app.directive('body', function() {
    return {
        restrict: 'E',
        compile: function(element, attr) {
            // find the inner element and wrap it
            $('.some-item-in-html', element).wrap('<div class="container"></div>');
        }
    }
});

父指令总是在子指令之前编译,因此您可以在 compile 属性中更改子指令的 DOM,而不必担心重新编译或重新链接指令。

[编辑]

感谢 Biagio 的以下编辑。

此方法不应与带有模板的指令一起使用,因为该元素将被分配给模板而不是子元素。

另一种选择是在 Angular 生命周期开始时运行的函数中进行 DOM 操作。

例如:

 app.run(function(){
       // find the inner element and wrap it
      $('.some-item-in-html').wrap('<div     class="container"></div>');
  });

【讨论】:

  • 我没想到。在这种情况下,我可能可以使用容器指令中的 compile 属性。我会试一试的。
  • 是的,应该也可以。只要确保您只操作孩子的 DOM。使用 'body' 作为指令很方便,因为一切都是 body 的子对象。
  • 哦,是的,容器指令使用模板,因此 compile 属性提供的元素是模板,而不是将被嵌入的内容。我尝试了您的建议并使用父指令手动插入包装器元素的工作方式与您编写它的方式相同。此外,简单地将“预处理”DOM 操作放在模块 run() 函数中也可以。我有点希望有另一个我们还没有想到的更像角度的选择......如果这有意义的话。
  • 确实有意义 - 此方法不应与带有模板的指令或使用嵌入的指令一起使用。
猜你喜欢
  • 2013-05-22
  • 2017-04-13
  • 2017-02-23
  • 2016-05-24
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 2014-11-14
  • 1970-01-01
相关资源
最近更新 更多