You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Mar 23, 2021. It is now read-only.
我们随后就可以用 myInstance 实例访问 myClass函数和它的属性。在Angular中可以用新的 Controller as 语法来以类似的方式实例化。它的声明和绑定如下:
// we declare as usual, just using the `this` Object instead of `$scope`app.controller('MainCtrl',function(){this.title='Some title';});
This is more of a class based setup, and when instantiating a Controller in the DOM we get to instantiate against a variable:
这更多的是基于类的设置,并且当实例化的Controller在DOM中可以获取对应的实例变量:
<divng-controller="MainCtrl as main">
// MainCtrl doesn't exist, we get the `main` instance only
</div>
要在DOM中显示 this.title, 需要通过实例名来引用:
<divng-controller="MainCtrl as main">
{{ main.title }}
</div>
Controller as 语法最大的作用就是避免使用嵌套作用域而导致作用域属性的混乱。我们经常会需要在当前作用域内引用父作用域中的属性。
类似下边这样:
<divng-controller="MainCtrl">
{{ title }}
<divng-controller="AnotherCtrl">
{{ title }}
<divng-controller="YetAnotherCtrl">
{{ title }}
</div></div></div>
The first time I used the Controller as syntax I was like “yeah, awesome!”, but then to use scope watchers or methods (such as $watch, $broadcast, $on etc.) we need to dependency inject $scope. Gargh, this is what we tried so hard to get away from. But then I realised this was awesome. Controller as的语法用起来是很爽,但是用作用域监听器或方法(像$watch, $broadcast, $on等等)时我们不是需要依赖注入$scope才行吗! 这个貌似是避免不了的。
The way the Controller as syntax works, is by binding the Controller to the current $scope rather than it being all one $scope-like class-like Object. 对我来说,关键把类和特殊Angular我分离开来。
When I need something above and beyond generic bindings, I introduce the magnificent $scope dependency to do something special, rather than ordinary.
Those special things include all the $scope methods, let’s look at an example:
app.controller('MainCtrl',function($scope){this.title='Some title';$scope.$on('someEventFiredFromElsewhere',function(event,data){// do something!});});
app.controller('MainCtrl',function($scope){this.title='Some title';// hmmm, a function$scope.$watch(function(){},function(newVal,oldVal){});});
也就意味着我们可以返回 this.title 的引用:
app.controller('MainCtrl',function($scope){this.title='Some title';// nearly there...$scope.$watch(function(){returnthis.title;// `this` isn't the `this` above!!},function(newVal,oldVal){});});
再用 angular.bind() 改变执行上下文:
app.controller('MainCtrl',function($scope){this.title='Some title';// boom$scope.$watch(angular.bind(this,function(){returnthis.title;// `this` IS the `this` above!!}),function(newVal,oldVal){// now we will pickup changes to newVal and oldVal});});
// Same test becomesdescribe('MainCtrl',function(){varscope;beforeEarch(function(){module('myModule');inject(function($controller,$rootScope){scope=$rootScope.$new();varlocalInjections={$scope: scope,};$controller('MainCtrl as main',localInjections);});});it('should expose title',function(){expect(scope.main.title).equal('Some title');});});
自1.2以来,Angular开发上有些细微变化,其中一个变化我相信有助于改善结构,使用作用域更加合理,并使controller变得更小。
Controller就像大家所了解的class-like对象,驱动模型和视图变更,但它们似乎是围绕着神秘的$scope对象来运作的。Angular的Controller已经改变了$scope的声明方式,因为很多开发人员建议用
this
关键字来替代$scope。v1.2.0之前的Controller看起来像这样:
Controller在这里和$scope是相互独立的, 必须依赖注入它。这样做可能会更好一些:
完全没有理解也没关系,以后就可以看到这样写的好处。
Controllers as 语法
如果在JavaScript中实例化一个 "class", 你也许会这么做:
我们随后就可以用
myInstance
实例访问myClass
函数和它的属性。在Angular中可以用新的Controller as
语法来以类似的方式实例化。它的声明和绑定如下:This is more of a class based setup, and when instantiating a Controller in the DOM we get to instantiate against a variable:
这更多的是基于类的设置,并且当实例化的Controller在DOM中可以获取对应的实例变量:
要在DOM中显示
this.title
, 需要通过实例名来引用:我认为给scope设置命名空间是一个很大的进步,它可以让Angular不变得那么臃肿。我不喜欢这种 "不受约束的变量"(floating variables), 类似
{{ title }}
, 我更喜欢在实例上调用, 像{{ main.title }}
。嵌套作用域(Nested scopes)
Controller as
语法最大的作用就是避免使用嵌套作用域而导致作用域属性的混乱。我们经常会需要在当前作用域内引用父作用域中的属性。类似下边这样:
三个
{{ title }}
很容易给人造成困扰,我们不清楚它们最终的值到底是什么。如果给它们清楚地指定属于哪个Controller的实例,则可以轻松地跨作用载访问这些属性:也同样可以不像下边这样访问父作用域:
像这样条理清楚地写:
不会再像那样没完没了地引用$parent。如果Controller的位置在DOM结构中发生改变,
$parent.$parent.$parent.$parent
这种引用序列有可能改变! 通过Controller实例别名访问作用域属性会更加合理。$watchers/$scope 方法
The first time I used the Controller as syntax I was like “yeah, awesome!”, but then to use scope watchers or methods (such as $watch, $broadcast, $on etc.) we need to dependency inject $scope. Gargh, this is what we tried so hard to get away from. But then I realised this was awesome.
Controller as
的语法用起来是很爽,但是用作用域监听器或方法(像$watch, $broadcast, $on等等)时我们不是需要依赖注入$scope才行吗! 这个貌似是避免不了的。The way the Controller as syntax works, is by binding the Controller to the current $scope rather than it being all one $scope-like class-like Object. 对我来说,关键把类和特殊Angular我分离开来。
这样就可以有一个完美的class-like控制器:
When I need something above and beyond generic bindings, I introduce the magnificent $scope dependency to do something special, rather than ordinary.
Those special things include all the $scope methods, let’s look at an example:
解决问题
下边提的
$scope.$watch
的示例,很简单,但很有意思的是,它没有像预期中那样生效:那该怎么办呢? 实际上你可以向$watch的第一个参数传递一个函数:
也就意味着我们可以返回
this.title
的引用:再用
angular.bind()
改变执行上下文:在$routeProvider/Directives/elsewhere中声明
Controller可以被动态设置,我们不需要总是通过属性绑定它们。在指令内部,像这样写
ControllerAs: property
, 很方便地设置:在
$routeProvider
内部也一样:在测试中使用 controllerAs 语法
测试中的
controllerAs
变化不大, 并且我们不再需要注入$scope了。意味着我们测试Controller时也不需要有一个属性的引用(类似 vm.prop), 我们可以简单地使用设置给$controller的变量名。你也可以在$controller中使用
controllerAs
语法, 不过你需要注入$scope实例到对象中并传入$controller。Controller的别名(scope.main的实例)将会添加到$scope中(像它在实际Angular应用中一样),然而这不是一个优雅的解决方案。The text was updated successfully, but these errors were encountered: