如何在编译内部指令之前修改transcluded内容?

jcu*_*bic 8 angularjs angularjs-directive

我想要做的是,在插入DOM之前手动处理transclude并修改内容:

return {
    restrict: 'E',
    transclude: true,
    template: '<HTML>',
    replace: true,
    link: function(scope, element, attrs, ngModelCtrl, $transclude) {

        var caption = element.find('.caption');

        $transclude(function(clone) {
            console.log(clone);
            clone.filter('li').addClass('ng-hide'); // this don't work
            clone.addClass('ng-hide'); // same this one
            clone.attr('ng-hide', 'true'); // same this one
            $compile(clone)(scope.$new()).appendTo(caption);
            caption.find('li').addClass('ng-hide'); // and this
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

在angular.js源代码中我找到了这个例子:

  var templateElement = angular.element('<p>{{total}}</p>'),
      scope = ....;

  var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) {
    //attach the clone to DOM document at the right place
  });

  //now we have reference to the cloned DOM via `clonedElement`
Run Code Online (Sandbox Code Playgroud)

但是当我添加clonedElement.appendTo(caption);内部链接功能时,它只会在ng-repeat内添加注释.

我需要这个,因为在这种情况下我需要隐藏所有元素

<dropdown>
  <li ng-repeat="item in items"><a>{{item.label}}</a></li>
</dropdown>
Run Code Online (Sandbox Code Playgroud)

我需要在扩展ng-repeat之后在编译或DOM之前修改模板.之前会更好,因为我可以使用ng-hide指令而不是ng-hide类添加逻辑.

小智 5

我意识到这个问题发布已经很长时间了,但我希望您会发现以下内容有用。

我在这个(嵌入)业务中已经很长时间了,我尝试了几种方法来实现您@jcubic 的需求,最后我找到了一个非常强大且非常简单的解决方案。

...
replace: false,
transclude: false,
compile: function( tElement, tAttributes ) {

    // store your "transcluded" content of the directive in the variable
    var htmlContent = tElement.html();
    // then remove it
    tElement.html('');

    return function postLink(scope, elem, attrs) {
        // then html var is available in your link! 
        var $html = $('<div />',{ html:htmlContent }); // for much easier manipulation (so you can use DOM functions - you can also manipulate directly on htmlContent string)

        // so you can manipulate the content however you want
        scope.myVariable = true;
        $html.find('li').attr('ng-hide', 'myVariable'); // add native directive
        $html.removeClass('inner-content').addClass('my-inner-content'); // add/remove class
        $html.find('#myElement').attr('my-directive',''); // add custom directive etc. etc.

        // after you finished you just need to compile your html and append your directive element - also however you want
        // you also convert back $html to the string
        elem.append( $compile( $html.html() )(scope) ); // append at the end of element
        /* or: 
        elem.find('.my-insert-point').html( $compile( $html.html() )(scope) ); // append the directive in the specific point
        elem.find('[my-transclude]').html( $compile( $html.html() )($parent.scope) ); // once the scope:true it will be the same as native transclusion ;-) 
        scope.variable = $html.html(); // or you can probably assign to variable and use in your template with bind-html-compile (https://github.com/incuna/angular-bind-html-compile) - may need $sce.trustAsHtml
        */
     }
}
...
Run Code Online (Sandbox Code Playgroud)

因此,如您所见,您可以完全控制“嵌入”的内容,甚至不需要嵌入!:-)

附:我用 Angular 1.4 对其进行了测试。不确定它是否适用于 replace:true (我没有费心去测试它,因为如果它没有,它会带来一些小麻烦)。您可以像通常在 compile 函数中使用的那样使用 pre 和 post 链接,并且需要将 $compile 服务注入到您的指令中。


Yan*_*rra 3

j立方。您不必使用 $compile 来完成您想要做的事情。

您可以过滤嵌入的元素“克隆”并将CSS类添加到过滤后的节点,但之后您必须将修改后的克隆附加到模板(它由链接函数的“元素”属性标识)。

element.append(clone)
Run Code Online (Sandbox Code Playgroud)

我 为你创建了这个jsfiddle 。

如果您还有其他问题,请创建您的案例的 jsfiddle。最好给出答案,谢谢