【问题标题】:How to make AngularJS compile the code generated by directive?如何让AngularJS编译指令生成的代码?
【发布时间】:2013-01-16 11:59:01
【问题描述】:

请帮帮我,我们怎样才能让AngularJS编译指令生成的代码?

你甚至可以在这里找到相同的代码,http://jsbin.com/obuqip/4/edit

HTML

<div ng-controller="myController">
    {{names[0]}} {{names[1]}}
    <br/> <hello-world my-username="names[0]"></hello-world>
    <br/> <hello-world my-username="names[1]"></hello-world>
    <br/><button ng-click="clicked()">Click Me</button>
</div>

Javascript

var components= angular.module('components', []);
components.controller("myController",
    function ($scope) {
        var counter = 1;
        $scope.names = ["Number0","lorem","Epsum"];
        $scope.clicked = function() {
            $scope.names[0] = "Number" + counter++;
        };
    }
);

// **Here is the directive code**
components.directive('helloWorld', function() {
    var directiveObj =  {
        link:function(scope, element, attrs) {
            var strTemplate, strUserT = attrs.myUsername || "";
            console.log(strUserT);
            if(strUserT) {
                strTemplate = "<DIV> Hello" + "{{" + strUserT +"}} </DIV>" ;
            } else {
                strTemplate = "<DIV>Sorry, No user to greet!</DIV>" ;
            }
            element.replaceWith(strTemplate);
        },
        restrict: 'E'
    };
    return directiveObj;
});

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    这是一个不使用编译函数和链接函数的版本:

    myApp.directive('helloWorld', function () {
      return {
        restrict: 'E',
        replace: true,
        scope: {
          myUsername: '@'
        },
        template: '<span><div ng-show="myUsername">Hello {{myUsername}}</div>'
        + '<div ng-hide="myUsername">Sorry, No user to greet!</div></span>',
      };
    });
    

    请注意,模板包含在 中,因为模板需要有一个根元素。 (如果没有 ,它将有两个

    根元素。)

    HTML 需要稍作修改,插入:

    <hello-world my-username="{{names[0]}}"></hello-world>
    

    Fiddle.

    【讨论】:

    • @Liviu,由于该指令不会更改 myUsername 值,因此单向数据绑定 ('@') 似乎比双向数据绑定 ('=') 更合适。虽然使用 '=' 更容易(无需在 HTML 中使用 {{}}),但使用 '@' 可以清楚地表明指令不需要修改值。
    • @MarkRajcok,最后评论中的信息非常好,我们希望通过博客或视频教程分享更多类似的信息。 ;)
    【解决方案2】:

    代码:http://jsbin.com/obuqip/9/edit

    components.directive('helloWorld', function() {
        var directiveObj =  {
            compile:function(element, attrs) {
                var strTemplate, strUserT = attrs.myUsername || "";
                console.log(strUserT);
                if(strUserT) {
                    strTemplate = "<DIV> Hello " + "{{" + strUserT +"}} </DIV>" ;
                } else {
                    strTemplate = "<DIV>Sorry, No user to greet!</DIV>" ;
                }
                element.replaceWith(strTemplate);
            },
            restrict: 'E'
        };
        return directiveObj;
    });
    

    说明:编译函数而不是链接函数应该使用相同的代码。 AngularJS 确实编译了 compile 函数的生成内容。

    【讨论】:

    • 因为element没有用在这个指令的链接函数版本中(Liviu的回答),我同意编译函数似乎更好。
    • 我刚刚发布了一个甚至不需要编译功能的答案。
    【解决方案3】:

    您需要从模板创建一个角度元素并使用$compile 服务

    jsBin

    components.directive('helloWorld', ['$compile', function(compile) {
        var directiveObj =  {
            link: function(scope, element, attrs) {
                var strTemplate, strUserT = attrs.myUsername || "";
                console.log(strUserT);
                if (strUserT) {
                    strTemplate = "<DIV> Hello" + "{{" + strUserT +"}} </DIV>" ;
                } else {
                    strTemplate = "<DIV>Sorry, No user to greet!</DIV>" ;
                }
    
                var e = angular.element(strTemplate);
                compile(e.contents())(scope);
                element.replaceWith(e);
            },
            template: function() {
                console.log(args);
                return "Hello";
            },
            restrict: 'E'
        };
        return directiveObj;
    }]);
    

    【讨论】:

    • stackoverflow.com/questions/12164138/…。通常这不是 1:1 指令的问题:html。 ng-repeat 和类似指令使用 compile 函数进行优化。
    • 这个答案包括来自 Misko stackoverflow.com/a/14359666/148869的解释
    • @Liviu,指令中template:的目的是什么?您是否尝试查看是否可以在那里生成两个版本的输出(发现它不起作用并且可能忘记删除代码)?我很想知道template: 是否可以带一个函数。
    • @MarkRajcok 实际上我只是修改了 OP 的解决方案以包含编译服务,坦率地说我没有看到其他参数:)
    猜你喜欢
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 2022-12-06
    • 2020-01-12
    • 2014-05-29
    相关资源
    最近更新 更多