Michal Foksa Michal Foksa - 2 months ago 29
Javascript Question

Ionic , AngularJs: Directive attribute $watch stops working after view is rendered

I want to create an attribute directive for ionItem and I want it to watch its own value:

<ion-item ng-repeat="item in items" my-dir="{{data.watchedValue}}">….</ion-item>


I have an issue with creating correct watch statement in the directive. The watch is executed only once during initial view rendering. After that it is not invoked when
data.watchedValue
is changed.

Specific of the directive is that it is child of
ionItem
directive.

I have tried multiple approaches (see comments in my-dir source), but none of them works.

Directive:

.directive('myDir', function() {
return {
restrict: 'A',
require: '^ionItem',
link: function(scope, element, attr, itemCtrl) {
console.log('my-dir initial value: ' + attr.myDir);

if (angular.isDefined(attr.myDir)) {
// scope.$watch("(" + attr.myDir + " === \"true\")", function(value) {
// scope.$watch('!!(' + attr.myDir + ')', function(value) {
scope.$watch(attr.myDir, function(value) {
console.log('my-dir watch new value: ' + value);
});
}

} // link
}; // return
}) // directive


Simplified directive usage:

<button class="button" ng-click="data.watchedValue = !data.watchedValue">
Change Value
</button>

<ion-content>
<ion-list>
<ion-item ng-repeat="item in items" my-dir="{{data.watchedValue}}">
Item {{ item.id }}. Watched property: {{ data.watchedValue }}
</ion-item>
</ion-list>
</ion-content>


Code Pen with full example. Press
Change Value
button to … change value.

Watch the console for any logs after initial display.

Answer

You should be just passing scope variable name to directive attribute

<ion-item ng-repeat="item in items" my-dir="data.watchedValue">
  Item {{ item.id }}. Watched property: {{ data.watchedValue }}
</ion-item>

OR

you could use attrs.$observe instead of $scope.$watch, which will basically keep an watch on {{}} interpolated value specified on attribute.

If data.watchedValue has object then I'd highly recommend to go for 1st approach.