咱們在定義路由時html
.state('account.register', { url: '/register', templateUrl: 'app/account/register.html', controller: 'RegisterCtrl', controllrtAs: 'vm' })
在angular的源代碼中:node
locals.$scope[state.controllerAs] = controllerInstance;
能夠發現angular把控制器的實例做爲$scope上以controllerAs的值爲名稱的對象屬性上了。
咱們用Batarang查看一下angularjs
發現確實是這樣。web
$scope是基於原型進行繼承的,好比說當咱們查找一個user對象時,angular會先查找當前$scope有沒有user,若是沒有的話就繼續往上層$scope查找,直至$rootScope。
而在controllerAs中,假設咱們使用controllerAschrome
UserCtrl as ctrl
angular將控制器自身掛載在$scope上,user也變爲ctrl.user,就不會存在上述的一層層查找的過程。在不少狀況下,好比在嵌套的路由中,上述$scope基於原型的查找,有時候確實會提供一些便利,但這些均可以用服務來實現,也應該使用服務來實現。app
你們在初次接觸angular時必定會被推薦過將全部數據都綁定在$scope的一個對象上(好比$scope.data)來避免一些js中值的複製和對象的引用可能會形成的一些問題(公司裏的新人大部分也確實遇到過這類問題),而使用controllerAs後就不須要這一步了,由於人家原本就是。學習
由於不使用$scope也就不能使用$on,$watch,$emit之類的方法,這些方法原本就應該儘可能少用,這樣就能夠更好的控制項目中的代碼,當不得不用這類方法時能夠參考下面的案例。this
便於新人學習,我發現新人對於$scope這個東西每每沒法理解,而用controllerAs vm以後,則將vm(view model的簡寫)做爲視圖模型則比較好理解。google
當出現這種狀況時咱們能夠把$scope當作單純的一種服務來使用,他提供了上述的方法,好比:url
function MyCtrl ($scope) { var vm = this; vm.name = 'liulei'; vm.count = 0; $scope.$watch('vm.count', function (newVal, oldVal) { vm.count ++; }); }
在指令中若是不須要數據綁定時,咱們簡單的將scope這個選項設置爲true或者{}便可,可當咱們須要從外部綁定一個值或者對象到指令中該怎麼辦呢?由於咱們知道若是用scope選項的話,確定是綁定到指令的scope對象上的,這裏咱們直接使用bindToController選項便可,上代碼
'use strict'; angular.module('nodeInAction') .directive('countCard', function () { return { restrict: 'E', controllerAs: 'vm', scope: {}, bindToController: { icon: '@', title: '@', count: '@', unit: '@', colorStyle: '@' }, templateUrl: 'app/components/countCard/countCard.html', controller: function () { var vm = this; console.log(vm); } }; });
結果也是咱們想要的結果。bindToController的做用的做用也很好理解也就是將屬性綁定到controller自身上。
也能夠這樣寫
'use strict'; angular.module('nodeInAction') .directive('countCard', function () { return { restrict: 'E', scope: { icon: '@', title: '@', count: '@', unit: '@', colorStyle: '@' }, controllerAs: 'vm', bindToController: true, templateUrl: 'app/components/countCard/countCard.html', controller: function () { var vm = this; console.log(vm); } }; });
效果是同樣的。