Angularjs 如何在编译内部指令之前修改转包内容?

Angularjs 如何在编译内部指令之前修改转包内容?,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我想做的是手动处理transclude,并在插入DOM之前修改内容: return { restrict: 'E', transclude: true, template: '<HTML>', replace: true, link: function(scope, element, attrs, ngModelCtrl, $transclude) { var caption = element.find('.caption'

我想做的是手动处理transclude,并在插入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
        });
    }
}

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

jcubic。您不必使用$compile来完成您要做的事情

您可以过滤转置的元素“clone”,并将css类添加到过滤的节点,但之后必须将修改后的克隆附加到模板中(它由link函数的“element”属性标识)

我为你创造了这个


如果您还有其他问题,请为您的案例创建一个JSFIDLE。如果您在模板中使用angular>1.3和ngTransclude,则最好回答Thx

,因此您需要更新的不是克隆,而是转置的DOM,例如:

elm.find('ng-transclude')


但是,如果您更新了一些您需要从controller访问的元素,请务必找到这些元素。我意识到这个问题发布已经很久了,但我希望您会发现以下内容很有用

我从事这项(转换)业务已经很长时间了,我尝试了几种方法来满足您@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
        */
     }
}
...
。。。
替换:false,
排除:错误,
编译:函数(远程通讯、属性){
//将指令的“转置”内容存储在变量中
var htmlContent=tElement.html();
//然后移除它
html(“”);
返回函数postLink(范围、元素、属性){
//然后html变量在您的链接中可用!
var$html=$('',{html:htmlContent});//更易于操作(因此您可以使用DOM函数,也可以直接在htmlContent字符串上操作)
//因此,您可以随心所欲地操纵内容
scope.myVariable=true;
$html.find('li').attr('ng-hide','myVariable');//添加本机指令
$html.removeClass('inner-content').addClass('my-inner-content');//添加/删除类
$html.find('#myElement').attr('my-directive','');//添加自定义指令等。
//完成后,您只需要编译html并附加指令元素——也可以按照您的意愿
//还可以将$html转换回字符串
append($compile($html.html())(scope));//在元素末尾追加
/*或:
elem.find('.my insert point').html($compile($html.html())(scope));//在特定点中追加指令
elem.find(“[my transclude]”).html($compile($html.html())($parent.scope));//一旦作用域为true,它将与本机转换相同;-)
scope.variable=$html.html();//或者您可以将变量赋值,并在模板中使用bind html compile(https://github.com/incuna/angular-bind-html-compile)-可能需要$sce.trustAsHtml
*/
}
}
...
因此,正如您所看到的,您可以完全控制“转置”内容,甚至不需要转置!:-)

另外,我用角度1.4测试了它。不确定它是否能与replace:true一起工作(如果不能,我就不用麻烦去测试它了,因为它只是一个小麻烦)。您可以像在compile函数中通常使用的那样使用pre和post链接,并且需要将$compile服务注入指令中

element.append(clone)
elm.find('ng-transclude')
...
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
        */
     }
}
...