修改指令中的模板(动态添加另一个指令)

时间:2013-03-11 23:26:19

标签: javascript angularjs angularjs-directive

问题

通过自定义指令动态添加 ng-bind 属性,以便能够使用 ng-bind,ng-bind-html ng-bind-自定义指令中的html-unsafe ,无需在任何地方手动添加模板定义。

实施例

http://jsfiddle.net/nstuart/hUxp7/2/

指令破碎

angular.module('app').directive('bindTest', [
'$compile',
function ($compile) {
    return {
        restrict: 'A',
        scope: true,
        compile: function (tElem, tAttrs) {
            if (!tElem.attr('ng-bind')) {
                tElem.attr('ng-bind', 'content');
                $compile(tElem)
            }
            return function (scope, elem, attrs) {
                console.log('Linking...');
                scope.content = "Content!";
            };
        }
    };
}]);

解决方案

不知道。真的我无法弄清楚为什么像上面的小提琴不起作用。在那里尝试使用额外的 $ compile

解决方法

我可以解决它可能在指令中添加模板值,但是将内容包装在一个额外的div中,如果可能的话我希望能够这样做。 (见小提琴)

第二种解决方法

请参阅此处的小提琴:http://jsfiddle.net/nstuart/hUxp7/4/(如Ikarus博士所建议)。我现在正在考虑这个解决方法,因为它仍然感觉你应该能够在到达链接功能之前修改模板,并且应该找到/应用更改。

4 个答案:

答案 0 :(得分:2)

您可以在链接功能中执行编译部分,如下所示:

angular.module('app').directive('bindTest', ['$compile', function ($compile) {
    return {
        restrict: 'A',
        scope: true,
        link: {
            post: function(scope, element, attrs){
                if (!element.attr('ng-bind')) {
                    element.attr('ng-bind', 'content');
                    var compiledElement = $compile(element)(scope);
                }
                console.log('Linking...');
                scope.content = "Content!";                
            }
        }
    };
}]);

让我知道这对您有多好http://jsfiddle.net/bPCFj/

答案 1 :(得分:2)

这种方式似乎更优雅(不依赖于$ compile)并适合您的情况:

angular.module('app').directive('myCustomDirective', function () {
    return {
        restrict: 'A',
        scope: {},
        template: function(tElem, tAttrs) {
            return tAttrs['ng-bind'];
        },
        link: function (scope, elem) {
            scope.content = "Happy!";
        }
    };
});

jsFiddle:http://jsfiddle.net/hUxp7/8/

来自Angular directive documentation您可以将模板指定为表示模板的字符串,或者将函数指定为带有两个参数tElement和tAttrs的函数(在下面的编译函数api中描述),并返回表示模板的字符串值。

答案 2 :(得分:1)

源代码告诉所有人!查看compileNodes() function and its use of collectDirectives()

首先,collectDirectives在单个节点上查找所有指令。在我们收集了该节点上的所有指令后,然后将指令应用于该节点。

因此,当compile指令上的bindTest函数执行时,正在运行的$compile()超出了收集指令进行编译的程度。

$compile指令中对bindTest的额外调用无效,因为您没有将指令链接到$scope。您无法访问$scope函数中的compile,但您可以在link函数中使用相同的策略,您可以访问$scope < / p>

答案 3 :(得分:1)

你们这么亲密。

function MyDirective($compile) {
    function compileMyDirective(tElement) {
        tElement.attr('ng-bind', 'someScopeProp');

        return postLinkMyDirective;
    }

    function postLinkMyDirective(iScope, iElement, iAttrs) {
        if (!('ngBind' in iAttrs)) {
            // Before $compile is run below, `ng-bind` is just a DOM attribute
            // and thus is not in iAttrs yet.
            $compile(iElement)(iScope);
        }
    }

    var defObj = {
        compile: compileMyDirective,
        scope: {
            someScopeProp: '=myDirective'
        }
    };

    return defObj;
}

结果将是:

<ANY my-directive="'hello'" ng-bind="someScopeProp">hello</ANY>