咱们在定义路由时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); } }; });
效果是同样的。