AngularJs“ controller as”语法澄清?

我从 angularJS 关于 controller as xxx了解新的语法

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

想象:

enter image description here

好,所以我不会有参数 $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

Question

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

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

70919 次浏览

我相信当您拥有嵌套作用域时,一个特殊的优势是显而易见的。现在可以完全清楚属性引用来自哪个作用域。

关于它有很多事情。

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

弄清楚一个属性来自哪里也是非常有用的。

You can nest controllers and when reading the html it is pretty clear where every property comes.

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

For example, having two controllers, both with the same name 'name', You can do this:

<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>

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

我看到的 controller as语法的主要优点是,您可以将控制器作为类使用,而不仅仅是一些 $scope 修饰函数,并且可以利用继承性。我经常遇到这样一种情况,即有一个功能非常类似于许多控制器,最明显的事情是创建一个 BaseController类并从中继承。

Even though there's is $scope inheritence, which partially solves this problem, some folks prefer to write code in a more OOP manner, which in my opinion, makes the code easier to reason about and test.

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

据我所知,$scope 在 Angular 2.0中将被删除,或者至少我们如何看待 $scope 的使用。最好开始使用控制器作为接近2.0版本的版本。

视频链接 给你的更多讨论。

我发现主要的优势是一个更直观的 api,因为方法/属性直接与控制器实例关联,而不是与 scope 对象关联。基本上,在旧的方法中,控制器只是构建作用域对象的一种装饰。

Here are some more info on this: http://www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff

来源

使用 $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;


}


});

上面我们使用 $scope 对象控制器和视图创建具有三个变量和一个行为的 AddController,这两个对象控制器和视图相互通信。$scope 对象用于向视图传递数据和行为。它将视图和控制器粘合在一起。

$scope 对象实际上执行以下任务:

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

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

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

  4. The $scope object gets modified when a view changes and a view gets modified when the properties of the $scope object change

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

Using the “controller as” syntax and vm

We can rewrite the above controller using the controller as syntax and the vm variable as shown in the listing below:

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;


}


});

本质上,我们将这个变量赋值给一个变量 vm,然后将一个属性和行为附加到该变量。在视图中,我们可以使用控制器作为语法访问 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 对象并附加属性和行为。但是,通过使用控制器作为语法,代码在控制器上非常干净,并且只有别名在视图上可见。

Here are some steps to use the controller as syntax:

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

  2. 把它分配给一个局部变量。我更喜欢变量名为 vm,你可以选择任何你喜欢的名字。

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

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

  5. You can give any name to the alias. I prefer to use vm unless I’m not working with nested controllers.

在创建控制器时,使用 $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>

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

在结束这篇文章的时候,我会说,无论您想使用控制器作为语法还是使用 $scope 对象,这完全是您的选择。这两种方法都没有巨大的优缺点,只是考虑到视图中嵌套控制器之间的明显分离,作为上下文控制的语法的控制器更容易使用。