ng-bind在我的指令之后发生,所以我没有值

Nao*_*aor 7 javascript angularjs angularjs-directive

我有一个带有ng-bind指令的div元素:

<div ng-bind="sometext"></div>
Run Code Online (Sandbox Code Playgroud)

我有一个指令,它获取一个元素,检查它的值/文本,并根据内容为元素添加颜色.我正在使用这个指令:

<div ng-bind="sometext" my-directive></div>
Run Code Online (Sandbox Code Playgroud)

问题是,在指令执行时,div上没有值或文本,因为ng-bind尚未发生.
我正在使用element.text()获取文本.
知道如何在我的指令中提供文本吗?

Kay*_*ave 13

你的指令可能在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);
  });

});
Run Code Online (Sandbox Code Playgroud)

我们看到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());
            });           
        }
    };      
});
Run Code Online (Sandbox Code Playgroud)

您将注意到我将优先级设置为1.您需要确保此指令的ngBind监视位于监视队列中的监视之后.这将确保ngBind首先更新元素.

默认情况下,指令的链接功能运行后链接,因此$compile文档会注意到:

首先编译具有更高数字优先级的指令.预链接功能也按优先级顺序运行,但后链接功能以相反的顺序运行.

因此,由于ngBind优先级为0,超过0的任何东西都将确保您的指令的手表将在ngBind手表之后出现.

演示小提琴


rtc*_*rry 8

编辑2

另一种选择是使用ng-classng-style更改文本的颜色.然后,您根本不必创建新指令.

原始答案

我根本不会依赖ng-bind指令......在我看来,这似乎更加清晰.

<div ng-bind="someModel" my-directive="someModel"></div>
Run Code Online (Sandbox Code Playgroud)

然后将您的指令定义为......

angular.module('myApp').directive('myDirective', function() { 
    return {
        link: function(scope, element, attrs) {
            scope.$watch(attrs.myDirective, function(newValue, oldValue) {
              // Your Code here...
            });           
        }
    };      
});
Run Code Online (Sandbox Code Playgroud)

这样,即使您没有ng-bind元素,也可以使用您的指令(例如,如果您使用花括号).

<div my-directive="someModel">{{someModel}}</div>
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用attrs.$observe(...)(文档)而不是scope.$watch(...).

<div ng-bind="someModel" my-directive="{{someModel}}"></div>
Run Code Online (Sandbox Code Playgroud)

angular.module('myApp').directive('myDirective', function() { 
    return {
        link: function(scope, element, attrs) {
            attrs.$observe('myDirective', function(interpolatedValue) {
              // Your Code here...
            });           
        }
    };      
});
Run Code Online (Sandbox Code Playgroud)

您可以找到有关之间的差异的详细信息scope.$watch(...),并attrs.$observe() 在这里.

编辑

鉴于您的指令基本上是在ng-bind指令之后改变DOM ,为什么不ng-bind一起跳过所有这些?

<div my-directive="{{someModel}}"></div>
Run Code Online (Sandbox Code Playgroud)

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);
            });           
        }
    };      
});
Run Code Online (Sandbox Code Playgroud)