angular js指令中的“controller as”名称与父控制器中的函数相同

时间:2015-06-12 13:28:41

标签: javascript angularjs angularjs-directive angularjs-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作为控制器的简称。即使以同样的方式命名“子”控制器,我也从来没有遇到过这样的问题。

但是现在我尝试用指令做同样的事情,突然我的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>'
        };
    });

输出:

enter image description here

我知道我可以在控件中使用不同的名称,但是为什么会在第一时间发生这种情况?

有没有办法让它使用相同的名称?

1 个答案:

答案 0 :(得分:8)

您遇到的问题似乎与指令在与控制器定义为vm的范围相同的范围内执行这一事实有关。

您需要做的是在指令中创建新的范围 scope: {}

app.directive('testDirective', function() {
        return {
            restrict: 'EA',
            scope: {},
            controller: 'TestDirectiveController',
            controllerAs: 'vm',
            bindToController: true,
            template: '<div>{{ vm.title }}</div>'
        };
    });

这样,controllerAs应该在指令范围内创建一个新的vm属性。