【问题标题】:AngularJS asynchronous directive compilationAngularJS 异步指令编译
【发布时间】:2013-10-11 20:00:02
【问题描述】:

我正在编写一个 angularjs 应用程序(带有 node/express 后端)。我在我的范围内有一个通过服务异步填充(和重新填充)的对象。

对象的内容是一系列“问题”对象,为简单起见有“文本”和“类型”属性。

我想要实现的是能够为每种类型提供一个角度指令,并让这些指令正确呈现。因此,例如,如果服务器返回 [{type:'booleanquestion',text:'Is the sky blue?'}] 我将创建一个元素,然后 booleanquestion 指令将启动并适当地呈现它。

到目前为止,我已经定义了一个运行良好的“questionset”指令,观察问题集合并编译所需的内容,以便指令显示 correclt.y

HTML

<div questionset="questions"/>

app.js

...
scope.questions = questions; // e.g. [{text: 'some text',type: 'boolean'}]

directives.js

angular.module('myApp').directive('questionset',function($compile){
    return {
        transclude: 'true',
        compile: function(element,attr,linker){
            return function($scope,$element,$attr){
                var elements = [],
                    parent = $element.parent();

                $scope.$watchCollection('questions',function(questions){
                    var block, i, childScope;

                    if(elements.length > 0)
                    {
                        for( i = 0; i < elements.length ; i++)
                        {
                            elements[i].el.remove();
                            elements[i].scope.$destroy();
                        }
                        elements = [];
                    }
                    if(!questions) return;

                    for(i = 0; i < questions.length; i++)
                    {
                        childScope = $scope.$new();
                        childScope['question'] = questions[i];
                        var html = '<div class="'+questions[i].type+'"/>';
                        var e = angular.element(html);
                        block = {};
                        block.el = e;
                        block.scope = childScope;
                        $compile(e)(childScope);
                        element.append(e);
                        elements.push(block);
                    }
                });
            }
        }
    }
});

// For example, one type might be "boolean"
angular.module('myApp').directive('boolean',function($compile){
    return {
        restrict: 'AC',
        template: '<div class="question">{{question.text}}</div>',
        replace: true,
        link: function(scope,elem,attrs,ctrl){
            …….
       // for some reason, $compile will not be defined here?
        }
    };
});

虽然一切正常,但我有 2 个问题

1)。这是执行此操作的“正确”角度方式吗?这是我的第一个 Angular 项目,似乎我已经进入了最深的阶段(或者无论如何感觉就是这样)

2)。我的下一个目标是 question.text 能够包含 HTML 并被“编译”。例如,文本可能是

"Is the <strong>sky</strong> blue?"

我不确定如何进行这项工作 - 正如我在代码中的评论所暗示的那样,由于某种原因,$compile 没有被注入我的布尔指令中。也许这是因为我已经为它手动创建了子范围?我试图再次 $compile 元素的内容对吗?我觉得这最后一点可能很简单,但我没有看到它。

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    1) 我不知道。在我看来,整体方法看起来非常好;只需要打磨它,我们将在下面看到。

    2) 也许 $compile 在嵌套函数中不可用,因为它没有在父级中使用。尝试在父函数中引用 $compile 看看是否真的是这个原因:

    angular.module('achiive-vision').directive('boolean',function($compile){
        var justTesting = $compile;
        return {
            restrict: 'AC',
            template: '<div class="question">{{question.text}}</div>',
            replace: true,
            link: function(scope,elem,attrs,ctrl){
                …….
           // check if $compile is defined here now
            }
        };
    });
    

    我会通过将questionset 元素 html 更改为:

    var html = '<div class="question ' + questions[i].type + '">'
               + questions[i].text + '</div>';
    

    这样,你不需要再次编译,你就已经有了 HTML 支持。

    还有就是有点奇怪

    var html = '<div class="'+questions[i].type+'"/>';
    

    上面,然后你将用类似的标记替换它:

    template: '<div class="question">{{question.text}}</div>',
    

    ...然后你想再次编译这个...

    在我看来,您不需要replace: true,也不需要问题类型指令中的template。实现行为和其他任何东西,但让父 questionset 包含问题文本并编译它 - 一切都准备好了。

    另外,一个细节:我不会在循环中使用var htmlvar e。我会将它们添加到上面的列表中:

    var block, i, childScope, html, e;
    

    (另外,我会避免将变量命名为“i”和“e”...)

    这些是我关于您的代码的 cmets。正如我所说,我认为这种方法非常好,而不是对刚开始使用 AngularJS 的人说“高级”。我自己只用了不到两个月。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 1970-01-01
      • 2013-08-26
      • 2014-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多