使用带有指令的ControllerAs

时间:2015-08-06 13:56:48

标签: angularjs angularjs-directive angularjs-controlleras

我试图遵循John Papa的angularJS风格指南here,并开始将我的指令转换为使用controllerAs。但是,这不起作用。我的模板似乎无法访问分配给vm的任何内容。请参阅这个展示行为的非常简单的plnkr示例。

http://plnkr.co/edit/bVl1TcxlZLZ7oPCbk8sk?p=preview

angular
    .module('app', []);

angular
    .module('app')
    .directive('test', test);

function test() {
    return {
        restrict: 'E',
        template: '<button ng-click="click">{{text}}</button>',
        controller: testCtrl,
        controllerAs: 'vm'
    }
}

angular
    .module('app')
    .controller('testCtrl', testCtrl);

function testCtrl() {
  var vm = this;
  vm.text = "TEST";
}

5 个答案:

答案 0 :(得分:37)

当使用controllerAs语法时,您不像通常那样访问$ scope,变量vm被添加到范围中,因此您的按钮需要变为:

<button ng-click="click">{{vm.text}}</button>

请注意vm.添加到text的开头。

Here is a fork of your Plunk with the fix applied

问:你知道我如何访问作为属性传递给属性的属性,例如“scope:{text:'@'}”?我是否被迫在控制器上使用$ scope并设置vm.text = $ scope.text?

答:在您引用的文章中,a section y075只讨论了这种情况。查看bindToController

return {
    restrict: 'E',
    template: '<button ng-click="click">{{text}}</button>',
    controller: testCtrl,
    controllerAs: 'vm',
    scope: {
        text: '@'
    },
    bindToController: true // because the scope is isolated
};

然后您应该可以访问vm.text

答案 1 :(得分:4)

使用“controllerAs”,控制器实例别名 - vm(在您的情况下)作为范围的.vm属性在范围上发布。

因此,要访问其属性(即控制器的属性),您需要指定{{vm.text}}ng-click="vm.click"

答案 2 :(得分:1)

使用 controllerAs 语法时,必须使用

bindToController: true

它可以在您的指令中使用。

答案 3 :(得分:1)

使用' controllerAs '语法时,如上所述,范围绑定到控制器的' this '引用。 因此,它允许我们在我们的控制器中引入一个新的命名空间('vm'),而无需将范围属性放在另一个对象文字中(比如 $ scope ) 。 因此,访问控制器范围内的任何内容都需要'vm'命名空间,如,

'<button ng-click="click">{{vm.text}}</button>'

答案 4 :(得分:0)

我意识到这张票已经很旧了。我将添加 0.02 美元,以防将来有人偶然发现。

首先,最好有一些围绕您要实现的目标的上下文,因为您似乎违反了设计规则。您的指令不需要知道控制器的内部工作原理,反之亦然。

我创建了一个简单的示例,说明如何在指令中设置按钮的标题。这里不需要控制器,我认为它只会让您的示例难以遵循。

var myApp = angular.module('myApp', []);

myApp.directive('myDirective', function() {
  return {
    scope: {
      caption: "@"
    },    
    template: '<button>{{caption}}</button>'
  };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>

<div ng-app="myApp">
  <my-directive caption="Hello World" />
</div>