【问题标题】:What can be the reason to use "controllerAs" property?使用“controllerAs”属性的原因是什么?
【发布时间】:2015-10-28 13:39:19
【问题描述】:

我正在编写 AngularJS 教程,我看到以下代码:

.state('index',{
  url:"/",
  templateUrl:"views/index.html",
  controller:"IndexCtrl",
  controllerAs:"index"
})

有人想要使用controllerAs 属性的原因是什么?

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    是的。更多信息:

    controllerAs 语法之前,方法和属性需要通过绑定到$scope 来向视图公开。使用controllerAs,您的控制器实例将绑定到$scope 作为您选择的属性。

    这样您就可以为控制器使用普通的旧 JavaScript 类。

    社论:这是一种更简洁的开发方法。使 Angular 易于编写测试的原因之一是您的控制器和组件不需要从框架基类继承。请参阅 Backbone 和 Ember。

    所以你的控制器看起来像旧样式(在 ES6 中为简单起见):

    YourController.$inject = ['$scope'];
    class YourController {
      
        constructor($scope) {
    
            $scope.myMethod = () => { . . . };
    
            $scope.myProperty = true;
        }
    }
    

    使用控制器作为

    class YourController {
      
        constructor() {
    
            this.myProperty = true;
        }
    
        myMethod() { . . . };
    }
    

    只是一个普通的旧类,而不是装饰或修补 $scope

    【讨论】:

    • 直到“这是一种更简洁的开发方法”之前,我一直和你在一起。现在我们有一个可发现的,但不是非常这样(因此 OP 的问题),参考曝光另外迫使你使用this,其中as Crockford describes 在客观上并不是很好:“在语言中使用this 使得谈论该语言变得更加困难。这就像与 Abbott 和 Costello 的结对编程。“但是如果我们不考虑主观角度,这个答案可以很好地准确反映为什么有人弯得这么低。 ;^D
    • this 和 new 是语言的一部分。 TypeScript 和/或 ESLint 等工具可以解决 Crockford 描述的问题,而无需忽略 JavaScript 的主要功能。
    • 只是指出您已经解释了为什么使用controllerAs,但是比 me 聪明的人至少可能不同意使用它无疑是一种改进. controllerAs 是一种约定,它比$scope 更深奥,后者已经为您提供了一个现成的公开引用的出路(尽管Roy's answer covers some edgy conditions where $scope strains)。在任何情况下,人们都可以而且经常会比听从 Crockford 的建议做得更糟。
    【解决方案2】:

    几件事:

    1.减少范围使用

    您可以简单地使用this 来加载您需要的所有内容,而不是加载控制器范围内的所有数据。

    例如:

    路线

    state('index',{
        url:"/",
        templateUrl:"views/index.html",
        controller:"ListCtrl",
        controllerAs:"list"
    })
    

    在控制器中

    angular.module('feed').controller('ListCtrl', function($scope, reddit){
        var vm   = this;
        vm.names = ["Michael", "Roy"];
    
    });
    

    在模板中:

    <ul>
        <li ng-repeat="name in list.names">
            <div>{{name}}</div>
        </li>
    </ul>
    

    2。正确使用范围

    当多个控制器发挥作用时,作用域就变得很棘手。使用controllerAs 方法可以解决这个问题。示例如下:

    错误:

    <span>Outside Controller: Your name is: {{username}}</span>
    <div ng-controller="SignupController">
        <span>Inside Controller: Your name is: {{username}}</span>
        <fieldset legend="User details">
            <input ng-model="username">
        </fieldset>
    </div>
    

    正确:

    <span>Outside Controller: Your name is: {{user.name}}</span>
    <div ng-controller="SignupController">
        <span>Inside Controller: Your name is: {{user.name}}</span>
        <fieldset legend="User details">
            <input ng-model="user.name">
        </fieldset>
    </div>
    

    找到一张让一切更清晰的图片

    礼貌AngularJs "controller as" syntax - clarification?

    【讨论】:

    • There are performance improvements as well if we minimize the use of $scope,但是怎么样?你能解释一下吗?我认为 controllerAlias 只是作为范围(为控制器创建的范围)上的属性添加,其值与控制器实例的值相同。因此,您当然不会直接最小化 $scope 的使用。我同意答案中的其他部分。
    • 在第 1 点中,`controller:"ListCtrl",` 如何链接到vm&lt;div&gt;{{name}}&lt;/div&gt; 不应该是 &lt;div&gt;{{vm.name}}&lt;/div&gt; 吗?
    【解决方案3】:

    您可以通过多种方式设置控制器,例如:

    $stateProvider.state('contacts', {
      template: '<h1>{{title}}</h1>',
      controller: function($scope){
        $scope.title = 'My Contacts';
      }
    })
    

    或者如果你已经在模块上定义了一个控制器,像这样:

    $stateProvider.state('contacts', {
      template: ...,
      controller: 'ContactsCtrl'
    })
    

    或者使用上面的controllerAs语法变成:

    $stateProvider.state('contacts', {
      template: '<h1>{{contact.title}}</h1>',
      controller: function(){
        this.title = 'My Contacts';
      },
      controllerAs: 'contact'
    })
    

    $stateProvider.state('contacts', {
      template: ...,
      controller: 'ContactsCtrl as contact'
    })
    

    或者对于更高级的需求,您可以使用 controllerProvider 为您动态返回一个控制器函数或字符串:

    $stateProvider.state('contacts', {
      template: ...,
      controllerProvider: function($stateParams) {
          var ctrlName = $stateParams.type + "Controller";
          return ctrlName;
      }
    })
    

    来源:https://github.com/angular-ui/ui-router/wiki#controllers

    简单地说,Controller as 语法有助于我们使用嵌套控制器。命名范围已明确定义,因此控制器之间不会发生冲突,因为您必须在 dot 之前说明要引用的控制器。

    <div ng-controller="Shell as shellVm">
      <h1>{{shellVm.title}}</h1>
      <article ng-controller="Customers as customersVm">
        <h2>{{customersVm.title}} in {{shellVm.title}}</h2>
        <ul ng-repeat="c in customersVm.customers">
          <li>{{c.name}}</li>
        </ul>
      </article>
    </div>
    

    也请参考AngularJs "controller as" syntax - clarification?

    【讨论】:

      【解决方案4】:

      也许你没有足够的谷歌搜索!

      http://toddmotto.com/digging-into-angulars-controller-as-syntax/

      正如名称“controllerAs”告诉我们的那样,它是控制器的别名,您可以使用该别名访问您的控制器。

      【讨论】:

        猜你喜欢
        • 2012-10-06
        • 1970-01-01
        • 2017-04-10
        • 1970-01-01
        • 2016-04-27
        • 2021-10-27
        • 1970-01-01
        • 2018-09-10
        • 1970-01-01
        相关资源
        最近更新 更多