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

时间:2014-01-22 15:58:34

标签: javascript angularjs

来自angularJS的关于controller as xxx

read about the new syntax
  

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

可视化:

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

问题

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

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

6 个答案:

答案 0 :(得分:160)

有几件事情。

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

明确属性的来源也非常有用。

你可以嵌套控制器,在阅读html时,很清楚每个属性的来源。

您还可以避免某些点规则问题。

例如,拥有两个名称为“name”的控制器,您可以这样做:

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

同样的例子,但阅读起来要清楚得多。

答案 1 :(得分:16)

我看到controller as语法的主要优点是你可以使用控制器作为类,而不仅仅是一些$ scope-decorating函数,并利用继承。我经常遇到这样一种情况:当一个功能与许多控制器非常相似时,最明显的事情就是创建一个BaseController类并从中继承。

即使这是$ scope inheritence,它部分地解决了这个问题,但有些人更喜欢以更多的OOP方式编写代码,在我看来,这使得代码更易于推理和测试。

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

答案 2 :(得分:12)

我相信当你有嵌套的范围时,一个特别的优势很明显。现在将完全清楚属性引用的范围。

答案 3 :(得分:7)

Source

使用$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. $ scope对象在视图更改时被修改,并且当$ scope对象的属性发生更改时视图被修改

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

    使用“controller as”语法和vm

    我们可以使用控制器作为语法和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;
    
        }
    
    });
    

    基本上我们将它分配给变量vm,然后将属性和行为附加到该变量。在视图中,我们可以使用controller作为语法访问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。

    6. 在创建控制器时,使用$ 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对象,都是你的选择。两者都没有巨大的优势或劣势,只要控制器作为您对上下文具有控制权的语法就更容易使用,因为视图上的嵌套控制器有明显的分离。

答案 4 :(得分:3)

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

以下是有关此内容的更多信息:http://www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff

答案 5 :(得分:2)

从我读过的内容中,$ scope将在Angular 2.0中删除,或者至少我们如何查看$ scope的使用。开始使用控制器可能会很好,就像2.0版的发布一样。

视频链接here有关此问题的更多讨论。