【问题标题】:How to modify transcluded content before compile inside directive?如何在编译内部指令之前修改嵌入的内容?
【发布时间】:2017-02-20 21:53:32
【问题描述】:

我想做的是在插入 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
        });
    }
}

在 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`

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

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

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

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

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

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

    我在这个(嵌入)业务中投入了相当长的时间和精力,我尝试了几种方法来满足您@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
            */
         }
    }
    ...
    

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

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

    【讨论】:

      【解决方案2】:

      立方。你不必使用 $compile 来做你想做的事情。

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

      element.append(clone)
      

      我为你创建了这个jsfiddle

      如果您还有其他问题,请为您的案例创建一个jsfiddle。回答会更好Thx

      【讨论】:

        【解决方案3】:

        如果您在模板中使用 angular > 1.3 和 ngTransclude,那么您需要更新的不是克隆,而是转入的 DOM,例如:

        elm.find('ng-transclude')
        

        http://jsfiddle.net/jhqkxgos/

        但是如果你更新了一些你需要从控制器访问的元素,一定要compile找到元素

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-03-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-04
          • 1970-01-01
          • 2015-06-17
          相关资源
          最近更新 更多