【问题标题】:AngularJs "controller as" syntax - clarification?AngularJs“控制器作为”语法 - 澄清?
【发布时间】:2014-02-12 19:09:17
【问题描述】:

read about the new syntax 来自 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

问题

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

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

【问题讨论】:

  • 这个视频解释得很好。 youtube.com/watch?v=tTihyXaz4Bo 我认为它是用于 HTML 中更简洁的代码。
  • 清晰度。我不介意在控制器中使用 $scope.x Vs this.x,但在我看来,绑定到 {{invoice.x}} 告诉我的不仅仅是 {{x}}(恕我直言)。另外,我想知道这是否解决了我听说的一个问题,即控制器中的非对象有问题(所以 things.x 会很好,但 x 会导致问题)。
  • @MattRoberts 解决您的最后一条评论 - 您引用的非对象问题与其说是角度问题,不如说是 javascript 原型继承的事实。有一个很好的解释为什么它发生在角度 here (以及为什么 controller as 修复它)。
  • 我将如何替换 $scope.$broadcast?在这个新案例中,因为我的 this.$broadcast 似乎不起作用
  • @Gaurav 您仍然可以将 $scope 服务注入您的控制器,即使您将控制器用作某些属性、方法等的语法。

标签: javascript angularjs


【解决方案1】:

我相信当您拥有嵌套范围时,一个特别的优势是显而易见的。现在将完全清楚属性引用的确切范围。

【讨论】:

    【解决方案2】:

    这有几件事。

    有些人不喜欢$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>
    

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

    【讨论】:

    • 还有一个很好的例子来说明为什么这种方法可能会让一些人感到困惑:stackoverflow.com/questions/25405543/…
    • 这在嵌套控制器时非常有用!
    • 我在您的答案的类似实施中遇到了麻烦,请参阅stackoverflow.com/questions/38315538
    • 这也允许您使用 es6 类作为您的控制器并引用 HTML 中的方法。 foo() { ... }$scope.foo = function() { ... } 干净得多。
    【解决方案3】:

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

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

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

    【讨论】:

    • 这应该会得到更多的支持,因为 Fiddle 真的很有帮助
    【解决方案4】:

    据我所知,$scope 将在 Angular 2.0 中被移除,或者至少我们如何看待 $scope 的使用。随着 2.0 版本的临​​近,开始使用控制器可能会很好。

    视频链接here更多讨论。

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

        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 对象的属性更改时被修改

        我们将属性附加到 $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,然后为其附加属性和行为。在视图中,我们可以使用控制器作为语法访问 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>
        

        如您所见,要访问父控制器的年龄属性,我们使用 $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 对象完全取决于您的选择。两者都没有太大的优势或劣势,只是鉴于视图上嵌套控制器的明确分离,控制器作为您可以控制上下文的语法更容易使用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-07-27
          • 1970-01-01
          • 1970-01-01
          • 2015-12-20
          • 2014-05-05
          • 1970-01-01
          • 2020-06-20
          • 1970-01-01
          相关资源
          最近更新 更多