Reputation: 1758
As far as I know using controller property on 'Directive Definition Object' will create a separate instance of that controller everytime a given directive is linked?
Now playing with controllerAs patters I can see that when each of directives is being compiled the controller factory function is being triggered giving a different result for this.data.hello method.
But in my view I'm getting last instance of that controller. Why is that? What am I missing?
js
angular.module('app', [])
.controller('customCtrl', function () {
console.log('controller');
this.data = {
hello: Math.floor(Math.random() * 200 + 1)
};
})
.directive('customDrv', function () {
var linkFn = function (scope, element, attrs, ctrl) {
console.log('link');
console.log(ctrl.data.hello);
};
return {
templateUrl: 'Home/CustomDrv',
restrict: 'E',
controller: 'customCtrl',
controllerAs: 'vm',
compile: function (element, attrs) {
console.log('compile');
return linkFn
}
}
})
Html
<custom-drv></custom-drv>
<custom-drv></custom-drv>
<custom-drv></custom-drv>
<custom-drv></custom-drv>
Plunker: https://plnkr.co/edit/HII9a7Ff6ryXuz6Fgzr6
Upvotes: 1
Views: 60
Reputation: 2155
To get the different result for this.data.hello method create isolated scope as -
angular.module('app', [])
.controller('customCtrl', function () {
//console.log('controller');
this.data = {
hello: Math.floor(Math.random() * 200 + 1)
};
})
.directive('customDrv', function () {
var linkFn = function (scope, element, attrs, ctrl) {
//console.log('link');
console.log(ctrl.data.hello);
};
return {
template: '<h1>{{vm.data.hello}}</h1>',
restrict: 'E',
scope: {},
controller: 'customCtrl',
controllerAs: 'vm',
compile: function (element, attrs) {
//console.log('compile');
return linkFn
}
}
})
Upvotes: 3
Reputation: 2569
this.data = {
hello: Math.floor(Math.random() * 200 + 1)
}
Sets data.hello only one time (on controller load). If you want a different outcome everytime you'd say:
this.data = {
hello: function(){
return Math.floor(Math.random() * 200 + 1);
}
}
And invoke it with
ctrl.data.hello()
Working plunkr
However you probably want to pass hello
function through the binding and not access it directly from the directive (better practice):
Markup:
<custom-drv hello="hello"></custom-drv>
Directive:
.directive('customDrv', function () {
var linkFn = function (scope, element, attrs, ctrl) {
console.log('link');
console.log(ctrl.hello);
};
return {
template: '<h1>{{vm.hello()}}</h1>',
restrict: 'E',
scope: {
hello: '&' //represent function binding
}
controller: 'customCtrl',
controllerAs: 'vm',
compile: function (element, attrs) {
console.log('compile');
return linkFn
}
}
})
Upvotes: 2