I've a controller with some items for ng-repeat and each item should get a random color so I use ng-style with a function in that controller called randColor(...).
app.controller('TestController', function() {
var vm = this;
vm.items = [ { name: 'item 1' } , { name: 'item 2'} ];
vm.randColor = function (item) {
if (!item) {
return 'red';
}
else if (!item.color)
{
var color = 'rgb('
+ _.random(0, 255) + ','
+ _.random(0, 255) + ','
+ _.random(0, 255) + ')';
item.color = color;
}
return item.color;
};
});
I'm using the "controller as" syntax for this and I usually always use vm as the short name of my controllers. I've never had a problem with doing so, even when naming "sub"-controllers the same way.
But now I've tried to do the same thing with a directive and suddenly my randColor(...) function stopped working.
Here is a plunker of my problem.
HTML:
<body ng-controller="TestController as vm">
<!-- This works -->
<h3>Without Directive (controllerAs: 'vm')</h3>
<div ng-repeat="item in vm.items">
<div ng-style="{ background: vm.randColor(item) }" class="container">
<h4>{{ item.name }}</h4>
<div ng-controller="TestDirectiveController as vm">
<div>{{ vm.title }}</div>
</div>
</div>
</div>
<!-- This works -->
<h3>Test Directive Alternative (controllerAs: 'directiveVM')</h3>
<div ng-repeat="item in vm.items">
<div ng-style="{ background: vm.randColor(item) }" class="container">
<h4>{{ item.name }}</h4>
<test-directive-alt></test-directive-alt>
</div>
</div>
<!-- This DOES NOT work -->
<h3>Test Directive (controllerAs: 'vm')</h3>
<div ng-repeat="item in vm.items">
<div ng-style="{ background: vm.randColor(item) }" class="container">
<h4>{{ item.name }}</h4>
<test-directive></test-directive>
</div>
</div>
</body>
JS:
app.controller('TestDirectiveController', function() {
var vm = this;
vm.title = 'test';
});
app.directive('testDirective', function() {
return {
restrict: 'EA',
controller: 'TestDirectiveController',
controllerAs: 'vm',
bindToController: true,
template: '<div>{{ vm.title }}</div>'
};
});
app.directive('testDirectiveAlt', function() {
return {
restrict: 'EA',
controller: 'TestDirectiveController',
controllerAs: 'directiveVM',
bindToController: true,
template: '<div>{{ directiveVM.title }}</div>'
};
});
Output:

I know I could just use a different name for the controller as in my example, but why does this happen in the first place?
And is there a way to get it working with the same name?
scope? The problem might be that the directive is using the the same scope as the one wherevmis defined. For that reason it might not work. You can add a scope to the directive.scope: trueit worked...there goes the last 3 hours of my life. You can formulate it to an answer if you want to get the credit for it! Thanks anyways :)