问题描述
限时送ChatGPT账号..我有一个控制器,其中包含一些用于 ng-repeat
的项目,每个项目都应该有一个随机颜色,所以我使用 ng-style
和该控制器中名为的函数randColor(...)
.
app.controller('TestController', function() {var vm = 这个;vm.items = [ { name: 'item 1' } , { name: 'item 2'} ];vm.randColor = 函数(项目){如果(!项目){返回红色";}否则如果(!item.color){var color = 'rgb('+ _.random(0, 255) + ','+ _.random(0, 255) + ','+ _.random(0, 255) + ')';item.color = 颜色;}返回 item.color;};});
我为此使用了controller as"语法,并且我通常总是使用 vm
作为我的控制器的简称.这样做我从来没有遇到过问题,即使以相同的方式命名子"控制器也是如此.
但现在我尝试用指令做同样的事情,突然我的 randColor(...)
函数停止工作.
这是我的问题的一个 plunker.
HTML:
<!-- 这有效--><h3>无指令(controllerAs:'vm')</h3><div ng-repeat="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><!-- 这有效--><h3>测试指令替代(controllerAs:'directiveVM')</h3><div ng-repeat="vm.items 中的项目"><div ng-style="{ background: vm.randColor(item) }" class="container"><h4>{{ item.name }}</h4><test-directive-alt></test-directive-alt>
<!-- 这不起作用--><h3>测试指令(controllerAs:'vm')</h3><div ng-repeat="vm.items 中的项目"><div ng-style="{ background: vm.randColor(item) }" class="container"><h4>{{ item.name }}</h4><测试指令></测试指令>
JS:
app.controller('TestDirectiveController', function() {var vm = 这个;vm.title = '测试';});app.directive('testDirective', function() {返回 {限制:'EA',控制器:'TestDirectiveController',控制器为:'vm',bindToController: 真,模板:'<div>{{ vm.title }}</div>'};});app.directive('testDirectiveAlt', function() {返回 {限制:'EA',控制器:'TestDirectiveController',controllerAs: 'directiveVM',bindToController: 真,模板:'<div>{{directiveVM.title}}</div>'};});
输出:
我知道我可以像在我的示例中一样为控制器使用不同的名称,但为什么会发生这种情况?
有没有办法让它使用相同的名称?
解决方案您面临的问题似乎与指令在与控制器定义为 <代码>虚拟机代码>.
您需要做的是在指令中创建一个新的作用域 scope: {}
.
app.directive('testDirective', function() {返回 {限制:'EA',范围: {},控制器:'TestDirectiveController',控制器为:'vm',bindToController: 真,模板:'<div>{{ vm.title }}</div>'};});
这样,controllerAs
应该在指令范围内创建一个新的 vm
属性.
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?
解决方案The problem you're facing seems to be related to the fact that the directive is being executed on the same scope as the scope where the controller is defined as vm
.
What you need to do is to create a new scope scope: {}
within the directive.
app.directive('testDirective', function() {
return {
restrict: 'EA',
scope: {},
controller: 'TestDirectiveController',
controllerAs: 'vm',
bindToController: true,
template: '<div>{{ vm.title }}</div>'
};
});
With that, the controllerAs
should create a new vm
attribute in the directive scope.
这篇关于相同的“控制器"角度js指令中的名称破坏了父控制器中的功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论