非法使用ngTransclude指令的模板!人工手动操作transclusion时 [英] Illegal use of ngTransclude directive in the template! when doing transclusion manually

查看:1827
本文介绍了非法使用ngTransclude指令的模板!人工手动操作transclusion时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我preciously问上,所以如果有可能在指令模板(克隆它,并在模板中插入它在两个地方)。

I preciously asked on SO if it was possible to transclude the inner contents of a directive twice in the directive template (clone it and insert it in two places in the template).

一个非常乐于助人的人帮我把这个plunkr在一起。

A very helpful person helped me put this plunkr together.

http://plnkr.co/edit/k2UB1o4CTHtZ1voS0OKN?p=$p$ PVIEW

这似乎在第一次工作。问题是当我用它使用transclusion本身的任何子元素。我得到的错误是...

It seems to work at first. The problem comes when I use any child element which uses transclusion itself. The error I get is...

[ngTransclude:孤儿]在模板中非法使用ngTransclude指令!需要找到transclusion没有父指令。元素:

例如我有如下定义按键指令。

For example I have a button directive with the following definition.

angular.module('s4p.directives').directive('s4pButton', function () {

    return {
        restrict: 'E',
        scope: {
            icon: '@'
        },
        transclude: true,
        replace: true,
        template: getTemplate
    };

    function getTemplate(element, attr) {

        var btnType = (typeof attr.type === 'undefined') ? 'button' : attr.type;

        return  '<button s4p-button type="' + btnType + '">'+
                    '<s4p-button-content ng-transclude></s4p-button-content>'+
                    '<s4p-button-icon ng-if="icon">'+
                        '<s4p-icon href="{{icon}}"></s4p-icon>'+
                    '</s4p-button-icon>'+
                '</button>';
    }

});

当我把我的工具栏按钮内的一个,它试图克隆它,我得到上述错误。

as soon as I put one of my buttons inside the tool bar and it tries to clone it I get the above error.

编辑:

新PLUNKR以饱满的例子

New PLUNKR with full example

http://plnkr.co/edit/uK8r4EA2IPRnYKfjWNVG?p=$p$ PVIEW

任何帮助将大大AP preciated。

Any help would be greatly appreciated.

推荐答案

该指令试图做双transclusion在transclude函数的一个调用。

Problem Code

The directive was trying to do the double transclusion in one invocation of the transclude function.

//PROBLEM Code
link: function(scope, element, attrs, controller, transclude) {
    transclude(function(clone, scope) {
        element.find('[transclude-main]').replaceWith(clone);
        element.find('[transclude-overflow]').replaceWith($compile(clone.clone())(scope));
    });
}

正确code

要transclude指令内容到模板中的两个地方,调用transclusion功能的两倍。

Correct Code

To transclude the directive contents into two places in the template, invoke the transclusion function twice.

app.directive('toolbar', function($compile) {
    return {
        restrict: 'E',
        scope: {},
        transclude: {

        },
        template: 
            '<toolbar-main><div transclude-main></div></toolbar-main>' +
            '<toolbar-overflow><div transclude-overflow></div></toolbar-overflow>',
        //CORRECTED code
        link: function(scope, element, attrs, controller, transclude) {
            transclude(scope, function(clone) {
                element.find('[transclude-main]').replaceWith(clone);
            });
            transclude(scope, function(clone) {
                element.find('[transclude-overflow]').replaceWith(clone);
            });
        }
    };
});

如果你需要新的作用域的transclusion,你可以用范围创建。$新的()

If you need new scopes for the transclusion, you can create them with scope.$new().

var newScope = scope.$new();
transclude(newScope, function(clone) {
    element.find('[transclude-main]').replaceWith(clone);
});

有关创建新的作用域的详细信息,请参见 AngularJS $ rootScope .scope API参考 - $新

For more information on creating new scopes, see AngularJS $rootScope.scope API Reference -- $new.

AngularJS jqLit​​e是jQuery的一个微小的,API兼容的子集,允许角来操作一个跨浏览器兼容的方式在DOM。 jqLit​​e具有一个非常小的足迹的目标只实现了最常用所需的功能 1

AngularJS jqLite is a tiny, API-compatible subset of jQuery that allows Angular to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most commonly needed functionality with the goal of having a very small footprint.1

jqLit​​e的找到方法不支持属性选择器。为了使
与jqLit​​e兼容上面的例子中,使用自定义标签的transclusion目标。

The find method of jqLite does not support attribute selectors. To make the above example compatible with jqLite, use custom tags for the transclusion targets.

app.directive('toolbar', function($compile) {
    return {
        restrict: 'E',
        scope: {},
        transclude: {},
        template: 
            '<toolbar-main><my-main></my-main></toolbar-main>' +
            '<toolbar-overflow><my-overflow></my-overflow></toolbar-overflow>',
        //CORRECTED code
        link: function(scope, element, attrs, controller, transclude) {
            transclude(scope, function(clone) {
                element.find('my-main').replaceWith(clone);
            });
            transclude(scope, function(clone) {
                element.find('my-overflow').replaceWith(clone);
            });
        }
    };
});

这样就没有必要将jQuery添加到应用程序的依赖关系。

This way there is no need to add jQuery to the app as a dependency.

这篇关于非法使用ngTransclude指令的模板!人工手动操作transclusion时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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