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 属性。