AngularJS中controllerAs与控制器内$ctrl的作用及关联问题
// 模态框初始化代码 var modalPromise = $uibModal.open({ templateUrl: ....., controllerAs: '$ctrl', size: 'lg', controller: function createController($uibModalInstance, items) { var itemsSelected = items.itemSelected; return $controller('ItemUpdateCtrl', { $uibModalInstance: $uibModalInstance, $http: $http, ...... }) } });
// ItemUpdateCtrl 控制器内部代码 var $ctrl = this;
controllerAs 配置的作用
这个配置是AngularJS 1.x 生态下UI Bootstrap模态框组件的标准配置项,核心作用是给模态框绑定的控制器实例声明一个模板可直接访问的别名:
- 不配置这个项时,模板需要用到的变量、方法都要挂载到注入的
$scope对象上,模板里直接写变量名访问,很容易因为作用域原型链的继承特性出现变量覆盖、上下文错乱的问题。 - 配置
controllerAs: '$ctrl'之后,框架会自动把当前控制器的实例对象,以$ctrl为属性名挂载到模态框模板对应的作用域上。你在控制器里给this挂载的所有属性、方法,模板里通过$ctrl.xxx的形式就能直接访问,是AngularJS官方推荐的控制器最佳实践,能有效规避作用域嵌套带来的各类诡异问题。
配置项的$ctrl和控制器内部$ctrl变量的关联
两者没有框架层面的强制绑定关系,只是社区约定俗成的同名写法而已:
- 控制器内部写的
var $ctrl = this;本质是普通的局部变量赋值,目的是把控制器构造函数运行时的this(也就是控制器实例本身)存到局部作用域里,避免后续写嵌套函数、异步回调的时候出现this指向漂移的问题。这个变量名没有强制要求,你完全可以改成var vm = this、var self = this,都不会影响控制器本身的逻辑运行。 - 而
controllerAs里配置的$ctrl,是框架拿到控制器实例后,往模板作用域挂载实例时用的属性名,和你控制器内部用什么变量存this没有任何关联。哪怕你控制器内部把存实例的变量改叫vm,只要controllerAs的值还是$ctrl,模板里就必须用$ctrl.xxx的形式才能访问到你挂在控制器实例上的内容。
绝大多数业务代码里两者都命名为$ctrl,只是AngularJS社区长期推广的统一命名规范,目的是降低代码阅读成本,避免同一个控制器实例在内部逻辑、模板里用不同名字指代的混乱情况,不是框架强制要求的绑定逻辑。
内容的提问来源于stack exchange,提问作者Mandroid
相关产品推荐
相关产品推荐

