如何在编译内部指令之前修改嵌入的内容? [英] How to modify transcluded content before compile inside directive?

查看:26
本文介绍了如何在编译内部指令之前修改嵌入的内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What I want to do, is to handle transclude by hand and modify the content before I insert into the DOM:

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
        });
    }
}

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

In angular.js source I found this example:

  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`

但是当我在链接函数中添加 clonedElement.appendTo(caption); 时,它只会添加带有 ng-repeat 的注释.

but when I add clonedElement.appendTo(caption); inside link function it only add comment with ng-repeat inside.

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

I need this because I need to hide all elements in this case

<dropdown>
  <li ng-repeat="item in items"><a>{{item.label}}</a></li>
</dropdown>

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

I need to modify the template before compile or DOM after ng-repeat is expanded. Before would be better because I will be able to add logic using ng-hide directive instead of ng-hide class.

推荐答案

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

I realise it's been a long time since this question was posted, but I hope you may find the following useful.

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

I've been quite long and heavily in this (transclusion) business, I tried a few ways to achieve what you @jcubic need and finally I came across a solution which is really robust and quite simple.

...
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
        */
     }
}
...

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

So as you can see you have full control on your "transcluded" content and you don't even need transclusion! :-)

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

ps. I tested it with Angular 1.4. Not sure if it works with replace:true (I wasn's bother to test it as it's minor nuisance if it doesn't). You can use pre and post link as normally you'd use within compile function and you need to inject $compile service into your directive.

这篇关于如何在编译内部指令之前修改嵌入的内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆