在隔离范围指令中,在范围上定义变量和在控制器上定义变量之间是否有任何区别?

时间:2015-07-29 18:58:58

标签: javascript angularjs scope

几个月前我读了this article about not using ng-controller并采纳了它背后的想法:角度应用程序应该是一组组件协同工作。

基本思想是你可以将isolate范围指令与他们自己的控制器一起使用,如下所示:

.directive('myAppContestantList', function() {
    return {
      scope: {},
      templateUrl: 'my_app_contestant_list.html',
      replace: true,
      controller: 'ContestantListCtrl',
      controllerAs: 'ctrl'
    };
  })
  .controller('ContestantListCtrl', function() {
    this.contestants = [
      {firstName: 'Rachel', lastName: 'Washington'},
      {firstName: 'Joshua', lastName: 'Foster'},
      {firstName: 'Samuel', lastName: 'Walker'},
      {firstName: 'Phyllis', lastName: 'Reynolds'}
    ];
  });

而不是在控制器中创建$scope的数据属性,而是使其成为this的属性(this是控制器本身)。在控制器上定义变量意味着您可以在html中引用数据,只需在数据前添加ctrl,因为这是您在controllerAs字段中输入的内容:

<li ng-repeat="contestant in ctrl.contestants">
    {{contestant.firstName}} {{contestant.lastName}}
</li>

这对我来说非常好,我开始嵌套指令而不是嵌套控制器,这解决了嵌套的$scope问题。

鉴于背景,我不明白为什么该文章主张在您的控制器而不是$scope上定义变量。确实以前$scope是一个很大的问题,因为一旦你有嵌套的范围,它就会变得一团糟,但是使用它提倡隔离范围指令的模式,在$scope上定义的变量永远不会泄漏

你也永远不会发现自己处于模板中有多个控制器的位置,所以controllerAs似乎也没用。

在使用模式在我的控制器上定义的变量几个月非常成功后,我这样说。我想知道是否/为什么这样做比在$ scope上定义它们更好,而不是盲目跟随文章。

是否可能与bindToController

有关

有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:1)

&#39; controllerAs + this&#39; recipe主要针对引入多个ng-controller和其他内置指令的复杂模板,因此控制器标识符可以非常好地处理范围继承。

另一方面具有孤立范围的指令假设属性主要用于与父范围交互,它不会引起范围继承问题,并且$scope在那里感觉很好。

在第二种情况下,为了使代码看起来更像Angular2而摆脱$scope是不切实际的,毕竟AngularJS的设计考虑了范围。问题中提到的文章是过度范围迫害的一个很好的例子,它在社区IMO中引起了太多关注。

以下是指令的简明示例:

app.directive('isolated', function () {
  return {
    scope: {
      'isolated': '@'
    },
    template: '{{::data}}',
    controller: function ($scope) {
      $scope.data = $scope.isolated + '!';
    },
    link: function (scope, element) {
      element.append("<br>DOM " + scope.data);
    }
  };
});

该指令可以得到改善&#39;通过消除范围&#39;无论如何:

app.directive('isolated', function () {
  return {
    scope: { // yikes!
      'isolated': '@'
    },
    template: '{{::vm.data}}',
    controller: function () {
      this.data = this.isolated + '!';
    },
    controllerAs: 'vm',
    bindToController: true,
    link: function (s___e, element, attrs, ctrl) {
      element.append("<br>DOM " + ctrl.data);
    }
  };
});

由于bindToController,它变得不那么冗长,只有模板被控制器标识符污染。这种转换看起来毫无用处,但如果模板有可能最终得到一堆ng-repeat,那么可能会节省一些时间。

这两种语法可能还有其他不明显的用例。例如。控制器this语句can be abstracted to separate service没有努力(但偶尔$scope.$...是一个killjoy)。

TL; DR:thiscontrollerAs语法结合使用最佳,如果代码依赖于HTML编程&#39;和带有继承范围的指令,但当app由具有隔离范围的web组件式指令组成时,它很少是必须的。