Using ControllerAs with a Directive

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-28 23:02:29

问题


I'm trying to follow John Papa's angularJS style guide here and have started switching my directives to using controllerAs. However, this is not working. My template cannot seem to access anything assigned to vm. See this very simple plnkr example that exhibits the behavior.

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";
}

回答1:


When using the controllerAs syntax you don't access the $scope as you would normally, the variable vm is added to the scope, so your button needs to become:

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

Notice the vm. added to the beginning of text.

Here is a fork of your Plunk with the fix applied


Q: Do you know how I would access attributes passed through as attributes to the directive, example "scope: { text: '@' }"? Am I then forced to use $scope on the controller and set vm.text = $scope.text?

A: In the article you reference, there is a section y075 that talks about just this scenario. Look into bindToController:

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

Then you should be able to access vm.text




回答2:


With "controllerAs", the controller instance alias - vm, in your case - is published on the scope as the .vm property of the scope.

So, to access its properties (i.e. the properties of the controller), you need to specify {{vm.text}} or ng-click="vm.click".




回答3:


When using 'controllerAs' syntax ,as above,the scope is bound to the controller’s 'this' reference. So it allows us to introduce a new namespace('vm' here) bound to our controller without the need to put scope properties in an additional object literal(say $scope). So accessing anything in controller's scope,requires 'vm' namespace, as,

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



回答4:


When you use controllerAs syntax, then you have to use

bindToController: true

it will work in your directive.



来源:https://stackoverflow.com/questions/31857735/using-controlleras-with-a-directive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!