AngularJs“控制器作为”语法澄清?

我读了 angularJS有关controller as xxx 的新语法

语法InvoiceController as invoice告诉Angular实例化控制器并将其保存在当前范围的变量发票中。

可视化:

在这里输入图像描述

好吧,所以我不会有我的控制器中的参数$scope和代码将更清洁的控制器。

我将不得不在视图中指定另一个别名

所以到现在我可以这样做:

 <input type="number" ng-model="qty" /> ....controller('InvoiceController', function($scope) { // do something with $scope.qty <--notice 

现在我可以这样做:

  <input type="number" ng-model="invoic.qty" /> <-- notice ....controller('InvoiceController', function() { // do something with this.qty <--notice 

这样做的目标是什么? 从一个地方移除并添加到另一个地方?

我会很高兴看到我错过了什么。

有几件事情。

有些人不喜欢$scope语法(不要问我为什么)。 他们说,他们可以用this 。 那是目标之一。

明确财产来自哪里也是非常有用的。

你可以嵌套控制器,当阅读html时,很清楚每个属性到底在哪里。

你也可以避免一些点规则问题。

例如,有两个同名的控制器,你可以这样做:

 <body ng-controller="ParentCtrl"> <input ng-model="name" /> {{name}} <div ng-controller="ChildCtrl"> <input ng-model="name" /> {{name}} - {{$parent.name}} </div> </body> 

你可以修改父母和孩子,没有问题。 但是您需要使用$parent来查看父级的名称,因为您已将其映射到您的子级控制器中。 在大量的HTML代码中, $parent可能是有问题的,你不知道这个名字来自哪里。

有了controller as你可以这样做:

 <body ng-controller="ParentCtrl as parent"> <input ng-model="parent.name" /> {{parent.name}} <div ng-controller="ChildCtrl as child"> <input ng-model="child.name" /> {{child.name}} - {{parent.name}} </div> </body> 

同样的例子,但更清晰的阅读。

  • $scope plunker
  • controller as plunker

controller as语法的主要优点我看到的是,你可以使用控制器作为类,而不是一些$范围装饰功能,并利用继承。 当有一个功能与一些控制器非常相似时,我经常遇到这种情况,而最明显的做法是创建一个BaseController类并继承它。

尽管有$ scope继承,这部分解决了这个问题,但有些人更喜欢用更多的OOP方式编写代码,在我看来,代码更容易推理和测试。

这是一个演示小提琴: http : //jsfiddle.net/HB7LU/5796/

当你有嵌套的作用域时,我相信一个特别的优点是很明显的。 现在可以清楚地知道属性参考的范围是什么。

资源

使用$scope object创建控制器和使用“controller as”语法和vm之间的区别

使用$ scope对象创建一个控制器

通常我们使用$ scope对象创建一个控制器,如下所示:

 myApp.controller("AddController", function ($scope) { $scope.number1; $scope.number2; $scope.result; $scope.add = function () { $scope.result = $scope.number1 + $scope.number2; } }); 

上面我们用三个变量和一个行为创建AddController,使用$ scope对象控制器和视图,它们相互交谈。 $ scope对象用于将数据和行为传递给视图。 它将视图和控制器粘合在一起。

本质上,$ scope对象执行以下任务:

  1. 将数据从控制器传递到视图

  2. 将行为从控制器传递到视图

  3. 将控制器和视图粘合在一起

  4. 当$ scope对象的属性改变时,$ scope对象在视图改变时被修改,并且视图被修改

我们将属性附加到$ scope对象以将数据和行为传递给视图。 在控制器中使用$ scope对象之前,我们需要将它作为依赖关系在控制器函数中传递。

使用“controller as”语法和vm

我们可以使用controller作为语法和vm变量来重写上面的控制器,如下所示:

 myApp.controller("AddVMController", function () { var vm = this; vm.number1 = undefined; vm.number2=undefined; vm.result =undefined; vm.add = function () { vm.result = vm.number1 + vm.number2; } }); 

本质上,我们将这个分配给一个变量虚拟机,然后附加一个属性和行为。 在视图上,我们可以使用控制器作为语法来访问AddVmController。 这在下面的清单中显示:

 <div ng-controller="AddVMController as vm"> <input ng-model="vm.number1" type="number" /> <input ng-model="vm.number2" type="number" /> <button class="btn btn-default" ng-click="vm.add()">Add</button> <h3>{{vm.result}}</h3> </div> 

当然,我们可以使用控制器中的“vm”以外的其他名称作为语法。 在引擎盖下,AngularJS创建$ scope对象并附加属性和行为。 但是,通过使用控制器作为语法,控制器上的代码非常干净,只有别名在视图中可见。

以下是使用控制器作为语法的一些步骤:

  1. 创建一个没有$ scope对象的控制器。

  2. 将其分配给一个局部变量。 我首选变量名称为vm,您可以选择任意名称。

  3. 将数据和行为附加到vm变量。

  4. 在视图中,使用控制器作为语法给控制器一个别名。

  5. 你可以给任何名称的别名。 我宁愿使用vm,除非我不使用嵌套控制器。

在创建控制器时,使用$ scope对象方法或控制器作为语法没有直接的优点或缺点。 这纯粹是一个选择的问题,但是,使用控制器作为语法使得控制器的JavaScript代码更具可读性并防止了与此上下文相关的任何问题。

嵌套在$ scope对象中的控制器方法

我们有两个控制器,如下所示:

 myApp.controller("ParentController", function ($scope) { $scope.name = "DJ"; $scope.age = 32; }); myApp.controller("ChildController", function ($scope) { $scope.age = 22; $scope.country = "India"; }); 

属性“age”在两个控制器内,在视图中,这两个控制器可以嵌套,如下面的清单所示:

 <div ng-controller="ParentController"> <h2>Name :{{name}} </h2> <h3>Age:{{age}}</h3> <div ng-controller="ChildController"> <h2>Parent Name :{{name}} </h2> <h3>Parent Age:{{$parent.age}}</h3> <h3>Child Age:{{age}}</h3> <h3>Country:{{country}}</h3> </div> </div> 

如您所见,要访问父控制器的age属性,我们使用$ parent.age。 背景分离在这里不是很清楚。 但是使用控制器作为语法,我们可以以更优雅的方式使用嵌套控制器。 假设我们有如下所列的控制器:

 myApp.controller("ParentVMController", function () { var vm = this; vm.name = "DJ"; vm.age = 32; }); myApp.controller("ChildVMController", function () { var vm = this; vm.age = 22; vm.country = "India"; }); 

在视图中,这两个控制器可以嵌套,如下所示:

 <div ng-controller="ParentVMController as parent"> <h2>Name :{{parent.name}} </h2> <h3>Age:{{parent.age}}</h3> <div ng-controller="ChildVMController as child"> <h2>Parent Name :{{parent.name}} </h2> <h3>Parent Age:{{parent.age}}</h3> <h3>Child Age:{{child.age}}</h3> <h3>Country:{{child.country}}</h3> </div> </div> 

在控制器中,作为语法,我们有更多的可读代码,可以使用父控制器的别名来访问父属性,而不是使用$ parent语法。

我将结束这篇文章,说纯粹是你的选择是否要使用控制器作为语法或$ scope对象。 没有任何巨大的优势或劣势,简单地说,控制器作为语法,你有上下文的控制是更容易处理,鉴于在视图上的嵌套控制器明确分离。

我发现主要的优点是更直观的api,因为方法/属性直接与控制器实例关联,而不是作用域对象。 基本上,用旧的方法,控制器就成了构建范围对象的一个​​装饰。

这里有一些关于这方面的更多信息: http : //www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff

从我读过的,$ scope将被删除在Angular 2.0中,或者至少我们如何看待$ scope的使用。 随着2.0版本的发布,开始使用控制器可能会很好。

视频链接在这里进行更多的讨论。