Angular Controller和controllerAs指令

时间:2016-05-16 13:14:53

标签: angularjs

学习角度所以有些时候事物不清楚时读取角度上的文章。在这里,我坚持要了解关键字控制器和控制器在指令中的用法或重要性。

代码来自http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html

app.controller('SomeController', function () {
  this.foo = 'bar';
});

app.directive('someDirective', function () {
  return {
    restrict: 'A',
    controller: 'SomeController',
    controllerAs: 'ctrl',
    template: '{{ctrl.foo}}'
  };
});

我想知道这两个关键字在指令中的重要性,它们是controller: 'SomeController', and controllerAs: 'ctrl',

请告诉我,如果我们不使用这两个关键字controller: 'SomeController', and controllerAs: 'ctrl',那么会发生什么或哪些会更糟?

请帮助我了解此关键字的使用或重要性controller: 'SomeController', and controllerAs: 'ctrl', in directive.感谢

4 个答案:

答案 0 :(得分:1)

如果您计划引用控制器对象,则需要controller。这就是你如何勾选它。

controllerAs允许您创建一个可以引用控制器的变量,而不是使用$scope

精选回答:

<html ng-app="app">

<head></head>

<body>
    <script src="node_modules/angular/angular.js"></script>
    <script>
        var app = angular.module('app', []);
        app.directive('fooDirective', function() {
        return {
                restrict: 'A',                       
                controller: function($scope) {
                    // No 'controllerAs' is defined, so we need another way
                    //  to expose this controller's API.
                    // We can use $scope instead.
                    $scope.foo = 'Hello from foo';
                },
                template: '{{foo}}'
            };
        });

        app.directive('barDirective', function() {
           return {
               restrict: 'A',
               controller: function() {
                   // We define a 'vm' variable and set it to this instance.
                   // Note, the name 'vm' is not important here. It's not public outside this controller.
                   //   The fact that the 'controllerAs' is also called 'vm' is just a coincidence/convention.
                   // You could simply use 'this.bar' if you prefer.
                   var vm = this;
                   vm.bar = 'Hello from bar';
               },
               // This allows us to reference objects on the controller's instance by
               //   a variable called 'vm'.
               controllerAs: 'vm',
               // Now we can reference objects on the controller using the 'controllerAs' 'vm' variable.
               template: '{{vm.bar}}'
           };
        });
    </script>

    <div foo-directive></div>
    <div bar-directive></div>
</body>

</html>

答案 1 :(得分:1)

您无需同时使用controllercontrollerAs。您可以使用简写:

controller: 'SomeController as ctrl'

关系是使用您提供的实例句柄as ctrl创建控制器的新实例并将其公开给模板。

如果您使用嵌套控制器 - 或者在视图中使用控制器的多个实例,这会派上用场。

更新回复评论

您不需要使用带有AngularJS指令的控制器。实际上,从AngularJS 1.5开始,您应该只在创建components而不是directives时使用控制器。

指令和组件在概念上类似。直到AngularJS,它们的所有组件都将被定义为指令。

指令在很多方面与元素(如ng-href)或事件(如ng-click)交互。

区分组件和指令的最简单方法是组件将具有模板。

Can't I just create a component using the directive link method?

你可以,但除非你有充分的理由,否则我不会推荐它。使用控制器允许您使用面向对象的类或原型来定义模板和用户的操作行为。

同样,这些控制器比指令链接功能更容易进行单元测试。

答案 2 :(得分:1)

其中一个主要优点,特别是如果您是AngularJS的新手,是确保子范围之间正确的数据绑定

只需使用此代码示例并尝试发现一些奇怪的内容:

&#13;
&#13;
angular
  .module('myApp', [])
  .controller('MainCtrl', ['$scope',
    function($scope) {
      $scope.truthyValue = true;

      $scope.foo = 'hello';
    }
  ]);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>

<div ng-app="myApp" ng-controller="MainCtrl">
  <p>Start by writing something in the first input. Then write something in the second one. Good job, you've broke AngularJS!</p>
  1.
  <input type="text" ng-model="foo">

  <div ng-if="truthyValue">
    2.
    <input type="text" ng-model="foo">
  </div>

  <div>$scope.foo: {{ foo }}</div>
</div>
&#13;
&#13;
&#13;

背后的原因是ngIf创建了一个继承父作用域的子作用域。你基本上改变了ngIf范围内的值,它不会影响其父范围的值。

最后,我认为controllerAs语法是一个重要的AngularJS最佳实践。如果你在学习过程的早期就已经习惯了它,那么你就会避免一些令人头疼的问题,想知道为什么你的代码不起作用,特别是当一切看起来都井然有序时。

答案 3 :(得分:0)

查看此plunkr code

以下是我的简单指令代码:

<body ng-app="app">
   <some-directive />
</body>

和HTML

this

因此,正如您所看到的,如果您需要访问控制器中针对controllerAs关键字定义的某个变量,则必须使用$scope。但如果它是针对color对象定义的,则只需使用其名称即可访问它。

例如,您可以使用{{color}}获取变量$scope,因为它是针对{{ctrl.name}}定义的,但您必须使用this作为“名称”定义反对this

我认为确实存在很大差异,正如this answer所说,

  

有些人不喜欢$ scope语法(不要问我原因)。他们说   他们可以使用{{1}}

同样来自他们的own website,您可以阅读有关此设计选择背后的动机,

  

使用控制器可以明显看出你是哪个控制器   当多个控制器应用于模板时访问模板   元件

希望它有所帮助。