Reputation: 2068
I'm trying to use "Component approach" from Angular2 in Angular1, and my directives should send properties to each other. I've written code like this:
Parent directive
angular
.module('myModule')
.controller('parentController', ParentController)
.directive('parentDirective', () => {
return {
restrict: 'E',
scope: {},
controller: 'parentController',
controllerAs: 'ctrl',
templateUrl: 'parent-template.html'
}
});
class ParentController {
constructor() {
this._increasableValue = 0;
setInterval(() => {
this._increasableValue += 1;
})
}
get increasableValue() { return this._increasableValue; }
}
parent-template.html
<div class="container">
<child-directive inc="{{ctrl.increasableValue}}"></child-directive>
</div>
Child directive
angular
.module('myModule')
.controller('childController', ChildController)
.directive('childDirective', () => {
return {
restrict: 'E',
scope: {
increasableValue: '@inc'
},
bindToController: true,
controller: 'childController',
controllerAs: 'ctrl',
templateUrl: 'child-template.html'
}
});
class ChildController {
set increasableValue(value) { this._increasableValue = value; }
get increasableValue() { return this._increasableValue; }
}
child-template.html
<div class="container">
<div>{{ctrl.increasableValue}}</div>
</div>
But the increasableValue
freezes on start value and do not changes at all. What should be done to get increasableValue
from parent directive and bind it to child?
UPD: Here is jsfiddle to demonstrate problem (look at the console too).
Upvotes: 0
Views: 51
Reputation: 13382
Yes you right! Problem is how you update your variable.
Angular not know, that value changed, and not call digest loop to update view.
Sample with $inteval service
angular.module('myModule', []);
var ParentController = (() => {
function ParentController($interval) {
this._increasableValue = 1;
var interval = $interval(() => {
this._increasableValue += 1;
console.log(this._increasableValue);
if (this._increasableValue > 20) {
$interval.cancel(interval);
}
}, 1000);
}
Object.defineProperty(ParentController.prototype, "increasableValue", {
get: function () { return this._increasableValue; },
enumerable: true,
configurable: true
});
return ParentController;
})()
var ChildController = (() => {
function ChildController() {}
Object.defineProperty(ChildController.prototype, "increasableValue", {
get: function () { return this._increasableValue; },
set: function (value) { this._increasableValue = value; },
enumerable: true,
configurable: true
});
return ChildController;
})();
angular
.module('myModule')
.controller('parentController', ParentController)
.directive('parentDirective', () => {
return {
restrict: 'E',
scope: {},
controller: 'parentController',
controllerAs: 'ctrl',
template: `
<div class="container">
<child-directive inc="ctrl.increasableValue"></child-directive>
</div>`
}
});
angular
.module('myModule')
.controller('childController', ChildController)
.directive('childDirective', () => {
return {
restrict: 'E',
scope: {
increasableValue: '=inc'
},
bindToController: true,
controller: 'childController',
controllerAs: 'ctrl',
template: `
<div class="container">
<div>{{ctrl.increasableValue}}</div>
</div>`
}
});
angular.bootstrap(document.getElementById('wrapper'), ['myModule'])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<div id="wrapper">
<parent-directive>Loading...</parent-directive>
</div>
UPDATE: Or you can simple call $digest function like this
angular.module('myModule', []);
var ParentController = (() => {
function ParentController($scope) {
this._increasableValue = 1;
var interval = setInterval(() => {
this._increasableValue += 1;
console.log(this._increasableValue);
$scope.$digest();
if (this._increasableValue > 5) {
clearInterval(interval);
}
}, 1000);
}
Object.defineProperty(ParentController.prototype, "increasableValue", {
get: function () { return this._increasableValue; },
enumerable: true,
configurable: true
});
return ParentController;
})()
var ChildController = (() => {
function ChildController() {}
Object.defineProperty(ChildController.prototype, "increasableValue", {
get: function () { return this._increasableValue; },
set: function (value) { this._increasableValue = value; },
enumerable: true,
configurable: true
});
return ChildController;
})();
angular
.module('myModule')
.controller('parentController', ParentController)
.directive('parentDirective', () => {
return {
restrict: 'E',
scope: {},
controller: 'parentController',
controllerAs: 'ctrl',
template: `
<div class="container">
<child-directive inc="ctrl.increasableValue"></child-directive>
</div>`
}
});
angular
.module('myModule')
.controller('childController', ChildController)
.directive('childDirective', () => {
return {
restrict: 'E',
scope: {
increasableValue: '=inc'
},
bindToController: true,
controller: 'childController',
controllerAs: 'ctrl',
template: `
<div class="container">
<div>{{ctrl.increasableValue}}</div>
</div>`
}
});
angular.bootstrap(document.getElementById('wrapper'), ['myModule'])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<div id="wrapper">
<parent-directive>Loading...</parent-directive>
</div>
Upvotes: 1