在隔离作用域指令中,在作用域上定义变量和在控制器上定义变量之间有什么区别吗?

In an isolate scope directive is there any difference between defining variables on scope and defining variables on the controller?

本文关键字:定义 变量 作用域 什么 区别 之间 控制器 指令 隔离      更新时间:2023-09-26

几个月前,我读了一篇关于不要使用ng-controller的文章,并采纳了它背后的理念:angular应用应该是一组协同工作的组件。

基本的想法是,你将使用独立的作用域指令和它们自己的控制器,像这样:

.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有关吗?

谁能给我指个方向吗?

确实,'controllerAs + this'配方主要针对引入多个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);
    }
  };
});

指令可以通过各种方式消除'作用域'来'改进':

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 s,则可以节省一些时间。

这两种语法可能还有其他不明显的用例。例如,控制器this语句可以抽象为零努力分离服务(但零星的$scope.$...是扫兴的)。

如果代码依赖于"HTML编程"和具有继承作用域的指令,那么

TL;DR: this在与controllerAs语法结合时效果最好,但当应用程序由具有隔离作用域的web组件式指令组成时,我认为它很少是必须的。