I have...">

Ng-bind happens after my directive, so I have no value

I have a div element with the ng-bind directive:

<div ng-bind="sometext"></div> 

I have a directive that receives an element, checks its value / text and adds color to the element according to the content. I use this directive as follows:

 <div ng-bind="sometext" my-directive></div> 

The problem is that during the execution of the directive there is no value or text in the div, since ng-bind has not happened yet.
I get text using element.text ().
Any idea how to make text available inside my directive?

+7
javascript angularjs angularjs-directive
source share
3 answers

Edit 2

Another option is to use ng-class or ng-style to change the color of the text. Then you do not need to create a new directive at all.

Original answer

I would not depend on the ng-bind directive at all ... It seems a lot cleaner in my opinion.

 <div ng-bind="someModel" my-directive="someModel"></div> 

And then define your directive as ...

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

That way you can use your directive even if you don't have an ng-bind element for the element (for example, if you use curly braces instead).

 <div my-directive="someModel">{{someModel}}</div> 

Alternatively, you can use attrs.$observe(...) ( documentation ) instead of scope.$watch(...) .

 <div ng-bind="someModel" my-directive="{{someModel}}"></div> 

and

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

Further information on the differences between scope.$watch(...) and attrs.$observe() can be found here.

Edit

Given that your directive basically mutates the DOM after the ng-bind directive, why not skip all ng-bind ?

 <div my-directive="{{someModel}}"></div> 

and

 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); }); } }; }); 
+8
source share

Your directive can be executed before ngBind bound this value - both your directive and ngBind are priorities 0, so you can either start from the ngBind , but a little later, but look at the ngBind source code to see the root of the problem:

 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); }); }); 

We see that ngBind does not immediately update the DOM, but rather puts the clock on the ngBind attribute. Thus, the element will not be updated until the clock starts in the next $digest cycle (therefore, $timeout works).

Thus, one option is to simulate ngBind and put your own clock on this attribute - then you will be updated every time the ngBind result 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()); }); } }; }); 

You will notice that I have set priority 1. You need to be sure that this time zone will be set after the ngBind clock in the browse queue. This will ensure that the item is updated using ngBind .

By default, the directory link function launches the post link, so $compile docs notes:

Directives with a high numerical priority are compiled first. The functions of the preliminary link are also executed in the order of priority, but after the link, the functions are performed in the reverse order.

Therefore, since ngBind is a priority of 0, everything that should be at 0 ensures that your clock with the directive appears after the ngBind clock.

demo violin

+13
source share

You can use the area. $ watch in your link function and watch for model changes. Each time you change the value, ng-bind will fire, and your directive will also be run regardless of the bg-bind directive and depends only on the module itself.

Sorry, I can’t present you a sample code like im on a tablet, answering your question.

0
source share

All Articles