相同的“控制器"角度js指令中的名称破坏了父控制器中的功能 [英] Same "controller as" name in angular js directive breaks function in parent controller

查看:26
本文介绍了相同的“控制器"角度js指令中的名称破坏了父控制器中的功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个控制器,其中包含一些用于 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屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆