angular 中的相同 "controller as" 名称 js 指令中断了父控制器中的函数
Same "controller as" name in angular js directive breaks function in parent controller
我有一个控制器,其中有一些 ng-repeat
的项目,每个项目都应该有一种随机颜色,所以我使用 ng-style
以及该控制器中名为 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;
};
});
我为此使用 "controller as" 语法,我通常总是使用 vm
作为我的控制器的简称。我这样做从来没有遇到过问题,即使以相同的方式命名 "sub"-控制器。
但现在我尝试用指令做同样的事情,突然我的 randColor(...)
函数停止工作。
Here is a plunker 我的问题。
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>'
};
});
输出:
我知道我可以像示例中那样为控制器使用不同的名称,但为什么首先会发生这种情况?
有没有办法让它使用相同的名称?
您遇到的问题似乎与以下事实有关:指令正在与控制器定义为 vm
的范围相同的范围内执行。
您需要做的是在指令中创建一个新范围scope: {}
。
app.directive('testDirective', function() {
return {
restrict: 'EA',
scope: {},
controller: 'TestDirectiveController',
controllerAs: 'vm',
bindToController: true,
template: '<div>{{ vm.title }}</div>'
};
});
这样,controllerAs
应该在指令范围内创建一个新的 vm
属性。
我有一个控制器,其中有一些 ng-repeat
的项目,每个项目都应该有一种随机颜色,所以我使用 ng-style
以及该控制器中名为 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;
};
});
我为此使用 "controller as" 语法,我通常总是使用 vm
作为我的控制器的简称。我这样做从来没有遇到过问题,即使以相同的方式命名 "sub"-控制器。
但现在我尝试用指令做同样的事情,突然我的 randColor(...)
函数停止工作。
Here is a plunker 我的问题。
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>'
};
});
输出:
我知道我可以像示例中那样为控制器使用不同的名称,但为什么首先会发生这种情况?
有没有办法让它使用相同的名称?
您遇到的问题似乎与以下事实有关:指令正在与控制器定义为 vm
的范围相同的范围内执行。
您需要做的是在指令中创建一个新范围scope: {}
。
app.directive('testDirective', function() {
return {
restrict: 'EA',
scope: {},
controller: 'TestDirectiveController',
controllerAs: 'vm',
bindToController: true,
template: '<div>{{ vm.title }}</div>'
};
});
这样,controllerAs
应该在指令范围内创建一个新的 vm
属性。