分享人:熊凡
目录
1.背景介绍
2.知识剖析
3.常见问题
4.解决方案
5.编码实战
6.扩展思考
7.参考文献
8.更多讨论
在Angular中,有几种不同的方式来声明和使用控制器。
在最开始的时候我们对于angular在view上的绑定都必须使用直接的scope对象,对于controller来说我们也得必须注入$scope这个service
angular从1.2版本开始带来了新语法Controller as。
它使我们不需要把$scope作为依赖项。简洁了controller,同时我们可以使用this在控制器上直接添加我们想要的任何属性。
引入controller as之前:
app.controller('MainCtrl', function ($scope) {
$scope.title = 'Some title';
});
引入controller as之后:
app.controller('MainCtrl', function () {
var vm = this;
vm.title = 'Some title';
});
类比一下js中的构造函数和实例:
var myClass = function () {
this.title = 'Class title';
}
var myInstance = new myClass();
现在我们可以使用myInstance实例来访问myClass的属性和方法。
app.controller('MainCtrl', function () {
var vm = this;
vm.title = 'Some title';
});
{{ main.title }}
app.controller('MainCtrl',function(){})就是在定义一个名称为MainCtrl的构造函数,MainCtrl as main就是在实例化,生成MainCtrl的实例main,然后就可以在main中访问MainCtrl里定义的变量和函数。
scope对象类似于构造函数的原型对象
this则是指当前实例对象
controller as让继承关系的变量之间更清晰可读
var myClass = function () {
{{ title }}
{{ title }}
{{ title }}
{{ main.title }}
{{ another.title }}
{{ yet.title }}
var myClass = function () {
{{ title }}
Scope title: {{ title }}
Parent title: {{ $parent.title }}
{{ title }}
Parent title: {{ $parent.title }}
Parent parent title: {{ $parent.$parent.title }}
{{ main.title }}
Scope title: {{ another.title }}
Parent title: {{ main.title }}
{{ yet.title }}
Parent title: {{ another.title }}
Parent parent title: {{ main.title }}
controller as 方式解决了父子$scope带来的混乱
var myClass = function () {
ParentController:
ChildController:
直接使用$scope会产生父变字变,子变父不变的现象。当一个对象的原型链上有属性foo,你再给这个对象赋上一个属性foo,它不会改变原型链上的属性foo。只是新建的一个foo,在原型链的更近端,访问这个属性时不会在去寻找更远处的foo属性。
使用controller as方式可以避免上面的混乱,让关系更清晰:
ParentController:
parent.foo: {{ parent.foo }}
ChildController:
parent.foo: {{ parent.foo }}
controller as有哪些应用方式?
...
$routeProvider
.when('/my-url', {
controller: 'MyController',
controllerAs: 'ctrl'
});
$stateProvider
.state('myState', {
controller: 'MyController',
controllerAs: 'ctrl'
})
controller as的实质是什么?
controller as的实质是一种语法糖,我们可以看一下angular源码:
if (directive.controllerAs) {
locals.$scope[directive.controllerAs] = controllerInstance;
}
从上面的代码我们能看见的是:angular只是把controller这个对象实例以其as的别名在scope上创建了一个新的对象属性。
app.controller('MyController', function () {
this.someValue = "Hello!";
});
等价于:
app.controller('MyController', function ($scope) {
$scope.myController = this;
this.someValue = "Hello!";
}
谢谢大家
制作人: 熊凡