我有一个带有ng-bind指令的div元素:
<div ng-bind="sometext"></div>
我有一个指令,它获取一个元素,检查其值/文本,并根据内容为元素添加颜色。我使用这样的指令:
<div ng-bind="sometext" my-directive></div>
问题是,在执行指令时,div上没有值或文本,因为ng绑定还没有发生
我正在使用element.text()获取文本。
知道如何使文本在我的指令中可用吗?
您的指令可能在ngBind
绑定其值之前就已经运行了-您的指令和ngBind
的优先级都为0,因此两者都可以先运行,稍后再运行更多-但让我们查看ngBind
源代码以了解问题的根源:
var ngBindDirective = ngDirective(function(scope, element, attr) {
element.addClass('ng-binding').data('$binding', attr.ngBind);
scope.$watch(attr.ngBind, function ngBindWatchAction(value) {
element.text(value == undefined ? '' : value);
});
});
我们看到ngBind
不会立即更新DOM,而是对ngBind
属性进行监视。因此,在下一个$digest
周期运行该手表之前,元素不会更新(这就是$timeout
工作的原因)。
因此,一种选择是模仿ngBind
,并将您自己的手表放在其属性上,然后每当ngBind
结果发生变化时,您就会得到更新:
angular.module('myApp').directive('myDirective', function() {
return {
priority: 1,
link: function(scope,element,attrs) {
scope.$watch(attrs.ngBind, function(newvalue) {
console.log("element ",element.text());
});
}
};
});
你会注意到我将优先级设置为1。您确实需要确保此指令的监视位于监视队列中的ngBind
监视之后。这将确保ngBind
首先更新了该元素。
默认情况下,指令的链接函数在链接后运行,因此$compile
文档注意:
首先编译具有更高数字优先级的指令。预链接功能也按优先级顺序运行,但后链接函数按相反的顺序运行。
因此,由于ngBind
的优先级为0,任何超过0的值都将确保您指令的手表位于ngBind
手表之后。。
演示小提琴
编辑2
另一个选项是使用ng-class
或ng-style
来更改文本的颜色。那么你根本不需要创建一个新的指令。
原始答案
我根本不会依赖ng-bind
指令。。。在我看来,这似乎干净多了。
<div ng-bind="someModel" my-directive="someModel"></div>
然后将你的指令定义为…
angular.module('myApp').directive('myDirective', function() {
return {
link: function(scope, element, attrs) {
scope.$watch(attrs.myDirective, function(newValue, oldValue) {
// Your Code here...
});
}
};
});
这样,即使元素上没有ng-bind
,也可以使用指令(例如,如果使用大括号)。
<div my-directive="someModel">{{someModel}}</div>
或者,您可以使用attrs.$observe(...)
(文档)而不是scope.$watch(...)
。
<div ng-bind="someModel" my-directive="{{someModel}}"></div>
和
angular.module('myApp').directive('myDirective', function() {
return {
link: function(scope, element, attrs) {
attrs.$observe('myDirective', function(interpolatedValue) {
// Your Code here...
});
}
};
});
您可以在此处找到有关scope.$watch(...)
和attrs.$observe()
之间差异的更多信息。
编辑
既然您的指令基本上是在ng-bind
指令之后更改DOM,为什么不一起跳过ng-bind
呢?
<div my-directive="{{someModel}}"></div>
和
angular.module('myApp').directive('myDirective', function() {
return {
link: function(scope, element, attrs) {
attrs.$observe('myDirective', function(interpolatedValue) {
if (interpolatedValue) {
// Modify interpolatedValue if necessary...
}
element.text(interpolatedValue == undefined ? '' : interpolatedValue);
});
}
};
});
您可以使用作用域$在你的链接函数中观察,并观察模型的变化。每次值更改时,ng-bind将触发,您的指令也将被触发,独立于bg-bind指令,仅依赖于modle本身。
很抱歉,当我在平板电脑上回答你的问题时,我不能给你提供示例代码。