我正在尝试创建一个类似于以下使用的指令:
<amount value="myValue" neg-class="negative" />
myValue
是一个范围值(应该是一个数字)negative
只是一个css类的名称。
该指令背后的想法是,我不想向用户显示货币,当绑定的金额为负数时,negClass get将应用于呈现的元素。
我遇到的问题是,当negClass被更改时,更新不会生效。不过,我确实看到了DOM中的更改。
这是我的指令定义:
myModule.directive('amount', function () {
return {
restrict: 'E',
replace: true,
template: '<span ng-class="{ {{negClass}}: value < 0 }">{{value | currency}}</span>',
scope: {
value: "=",
negClass: "@",
}
};
});
以下是一个测试线束,用于说明问题:https://dl.dropboxusercontent.com/u/1563210/amtdirtest.html
大多数角度指令都倾向于以这种方式工作。除非文档特别提到支持输入的插值({{...}}
),否则不依赖它更安全,尤其是当输入是=而不是@绑定时。
在ngClass
的情况下,属性的工作方式类似于=绑定,并且没有提及插值。
指令中实际发生的情况是,只在链接阶段观察到属性,并且再也不会查看属性中的实际文本。因此,当属性继续更改时,这些更改永远不会出现。
当ngClass
看到属性时,它看起来有点像
{ n: value < 0 }
它仍然是基于当前value
在范围内的任何值来评估的,但表达式本身再也不会改变。
做你正在尝试的事情的安全方法是在不使用插值的情况下创建一个对象,或者只使用一个函数来返回哪个类是活动的。。。以下内容应该有效:
myModule.directive('amount', function () {
return {
restrict: 'E',
replace: true,
template: '<span ng-class="getActiveClass()">{{value | currency}}</span>',
scope: {
value: "=",
negClass: "@",
},
link: function(scope, element, attrs) {
scope.getActiveClass = function() {
if(scope.value < 0)
return scope.negClass;
}
}
};
});
最初没有注意到css已经在作用域中了。
以下是一种使用$compile
和$watch
动态编译元素的方法,以侦听negClass
中的更改
.directive('amount', function($compile) {
var template='<span ng-class="{ {{negClass}}: value < 0 }">{{value | currency}}</span>'
return {
restrict: 'E',
replace: true,
scope: {
value: "=",
negClass: "@",
},
link:function(scope,elem,attrs){
scope.$watch('negClass',function(){
elem.html('').append($compile(template)(scope) )
})
}
};
});
DEMO