3

问题

通过自定义指令动态添加ng-bind属性,以便能够在自定义指令中使用ng-bind、ng-bind-htmlng-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

4 回答 4

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/

于 2013-03-12T00:43:10.470 回答
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 指令文档您可以将模板指定为表示模板的字符串或作为接受两个参数 tElement 和 tAttrs(在下面的编译函数 api 中描述)并返回表示模板的字符串值的函数。

于 2014-01-26T23:29:27.330 回答
1

源代码说明一切!查看compileNodes()函数及其使用collectDirectives().

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

因此,当指令compile上的函数bindTest执行时,运行$compile()已经超出了收集要编译的指令的时间点。

$compile指令中的额外调用bindTest将​​不起作用,因为您没有将指令链接到$scope. 您无权访问函数$scope中的compile,但您可以在link有权访问$scope

于 2013-05-07T06:13:07.163 回答
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>
于 2015-08-07T00:44:20.120 回答