Angularjs Directive Does Not Update on Scope Variable Changes

AngularJS directive does not update on scope variable changes

You should create a bound scope variable and watch its changes:

return {
restrict: 'E',
scope: {
name: '='
},
link: function(scope) {
scope.$watch('name', function() {
// all the code here...
});
}
};

How to update directive when a scope variable changes?

First remove the interpolation:

<!--REMOVE interpolation
<div ng-app="app" words="{{search.keywords}}">{{search.results}}</div>
-->

<div ng-app="app" words="search.keywords">{{search.results}}</div>

Then use a watcher:

angular.module('app', []).directive('words', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.$watch(attrs.words, function(newValue) {
if (!newValue) return;

var words = newValue.split(' ');

for(var i=0; i<words.length; i++) {
var r = new RegExp(words[i], 'ig')
element.html(element.html().replace(r, '<span class="highlight">' + words[i] + '</span>'));
};
});
}

};
})

For more information, see AngularJS $rootScope.scope API Reference - $watch.

Angular $scope variable not updating

Actually this has been discussed in more links.

Don't use primitive type variable. Instead of that use object in scope.

For example,
Don't use like $scope.primitiveVariale instead of this $scope.object={primitiveVariale:null}

So in view use like object.primitiveVariale then this will be reflect in all the view. Please see the following links.

https://github.com/angular/angular.js/wiki/Understanding-Scopes

AngularJs: Why does scope inside my directive not update when async data arrives?

When Angular first runs your directive's controller function, your $scope.items === undefined, so when you do this.items = $scope.items, your this.items === undefined too.

That's it. After that there is nothing that changes this.items.

This is unlike $scope.items. $scope.items is two-way bound to the outer scope, so whenever Angular detects a change externally, it sets the isolated scope variable.

The easiest way (and most suitable, in my opinion) is to use the $scope property directly in the directive:

<div>
Inside directive
<ul ng-repeat="i in items">
<li>{{ i }}</li>
</ul>
</div>

If you want to use your controller as ViewModel instead of scope (I don't know why you would), you could do:

$scope.$watchCollection("items", function(newVal, oldVal) {
ctrl.items = newVal;
});

EDIT:

In Angular 1.3 you can also do bindToController: true in the directive's definition, so that the controller property "items" will get the two-way binding that $scope.items gets. Then, you don't even need to do this.items = $scope.items;:

Your forked plunker to illustrate.

change directive when scope variable changes

You need to give the directive access to fields by adding a binding for it:

scope: {
action: '@',
method: '@',
html: '=',
fields: '='
}

And HTML:

<dform fields="fields" ...

The value might be undefined the first time, then you don't want to call dform:

scope.$watch('fields', function(newValue, oldValue) {

if (newValue === oldValue) return;

var config = {
"html": newValue
};

elm.dform(config);
});

Update

With this HTML:

<div html="fields" dform></div>

You just need to watch html instead, no need for $parent or adding fields as a binding:

scope.$watch('html', ...

AngularJs - directive not updating controller variable

You seems to be made a typo in Directive Definition Object, where $scope should be scope.


I'd like to suggest few things to improve your current approach, rather than using watcher in parent controller method. You should pass a callback to directive and call it as soon as you're done with reader object loaded. Which turns out that your isolated scope will appear like below

restrict: 'A',
scope: {
callback: '&'
},

and then put new method inside controller where we will pass a file data to that method.

$scope.importData = function(data) {
DataManagementService.importData(newValue);
});

And then from element pass callback method correctly on directive

<input id="btnImport" type="file" es-file-read callback="importData(data)"/>

Call method from directive code correctly.

reader.onload = function (loadEvent) {
$scope.$apply(function () {
$scope.esFileRead= loadEvent.target.result;
$scope.callback({ item: $scope.esFileRead });
});
};


Related Topics



Leave a reply



Submit