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

IT技术 javascript angularjs
2021-02-05 18:34:22

从 angularJS 中阅读了有关新语法的信息controller as xxx

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

可视化:

在此处输入图片说明

好的,所以$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个回答

关于它有几件事。

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

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

这也允许您使用 es6 类作为控制器并引用 HTML 中的方法。foo() { ... }$scope.foo = function() { ... }.
2021-03-14 18:34:22
这在您嵌套控制器时非常有用!
2021-03-16 18:34:22
这里还有一个很好的例子说明为什么这种方法可能会让某些人感到困惑:stackoverflow.com/questions/25405543/...
2021-03-17 18:34:22
我在执行类似的答案时遇到问题,请参阅stackoverflow.com/questions/38315538
2021-04-06 18:34:22

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

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

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

这应该得到更多的赞成,因为小提琴真的很有帮助
2021-04-02 18:34:22

我相信当您有嵌套作用域时,一个特殊的优势就很明显了。现在将完全清楚属性引用来自哪个范围。

来源

$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 as 语法和 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>

如您所见,为了访问父控制器的 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>

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

我将在这篇文章的结尾说,无论您想使用控制器作为语法还是使用 $scope 对象,这完全是您的选择。两者都没有巨大的优势或劣势,只是考虑到视图上嵌套控制器中的清晰分离,控制器作为您在上下文中控制的语法更容易使用。

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

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