ng-repeat中的自定义指令:为什么ng-style不适用?

时间:2015-03-07 10:57:52

标签: javascript angularjs angularjs-directive

我有一个自定义指令myItems,它通过myItem使用另一个指令ng-repeat呈现项目列表:

app.directive('myItems', function() {
    return {
        scope:{items:"="},
        restrict:"E",
        template:"<div my-item ng-repeat='item in items'></div>"
    };
});

每个项目都包含用于为元素设置样式的信息(例如颜色)。到目前为止,如果我使用模板方法,这种方法很好:

app.directive('myItem', function() {
    return {
        restrict:"A",
        template:"<div ng-style='{color:item.color}'>myItem: {{item.name}}</div>",
        replace:true
    };
});

为了支持更多涉及的功能,我现在想通过手动创建所有需要的东西(包括ng-style)来重建my-item相同的功能:

app.directive('myItem', function($compile) {
    return {
        restrict:"A",
        compile: function(element) {
            element.removeAttr('my-item');
            element.text('myItem: {{item.name}}');
            element.attr('ng-style', '{color:item.color}');    // Why does it have no effect?

            var compileElement = $compile(element);
            return function link(scope, elem, attr) {
                compileElement(scope);    // Why does binding with {{item.name}} even work without this statement?
            };
        }
    };
});

有趣的是,使用{{item.name}}的数据绑定功能正常,而ng-style却没有。

以下是显示上述两种方法的fiddle

我知道similar question。但我认为它不适用于此,因为我没有关于my-item指令范围的明确陈述。

2 个答案:

答案 0 :(得分:2)

编译函数有一个问题:在Angular“解析”该元素之后,它被调用为元素的指令。这意味着compile()函数的代码添加到包含正在编译的指令的元素的任何指令将不会被Angular 解析!这就是为什么{ {1}}被忽视。

另一方面,element.attr('ng-style', '{color:item.color}');是多余的;任何DOM操作完成内部包含正在编译的指令的元素,将由Angular 解析。

你能做什么?您的情况很简单,使用手表添加样式是一个简单的DOM操作(即使没有手表,如果您不希望颜色发生变化):

compileElement(scope);

答案 1 :(得分:0)

调用compileElement确实编译了ng-style元素,但因为在元素完全构造之前调用了$compile,所以调用compileElement处理元素的无效版本并且ng-风格没有改变颜色。

所以你可以在链接函数中移动$compile

var compileElement = $compile(elem);
compileElement(scope);

但是它还会再次编译ng-repeat指令,这是不好的。所以你也需要删除该属性:

element.removeAttr('ng-repeat');

检查this plunker