在 Angular 控制器中设置手表与更复杂的模板

Setting up watches in Angular controller vs. more complex template

我正在寻找合适的位置来放置一些与表示相关的逻辑 Angular。我是 Angular 的新手,所以我想要一些关于正确 Angular 解决此类问题的一般指导。

我有一个对象封装了用户对数据点列表的排序选择(称为 "samples")。排序可以是升序或降序,并且可以基于排序对象的描述或两个匹配集合之一的数值(测量值和缺陷)。

排序效果很好,但现在我想在屏幕上放置一个图例,显示排序的配置方式。这是我对指令的第一次尝试:

sampleSort.directive('sampleSortLegend', ['SampleSort', function(SampleSort) {
  return {
    restrict: 'E',
    controller: function($scope, $element, $attrs) {
      var classes = [];
      var name, directions;
      if (SampleSort.isByDescription()) {
        name = 'Sample Description';
        directions = ['A to Z', 'Z to A'];
      } else {
        name = SampleSort.elementName();
        if (SampleSort.isByDeficiency()) {
          clasess.add('deficiency');
        }
        directions = ['lowest to highest', 'highest to lowest'];
      }
      $scope.sortName = name;
      $scope.sortClasses = classes;
      $scope.sortDirection = SampleSort.isAscending() ? directions[0] : directions[1];
    },
    template: 'Sorted by: <strong ng-class="sortClasses">{{sortName}}</strong> ({{sortDirection}})',
  }
}]);

这给了我想要的结果,除了它是完全非交互的,因为这三个范围属性永远不会改变。要解决这个问题,最好是:

  1. 在控制器中设置一个 $watch 以在我的 SampleSort 的关键响应发生变化时更新范围;
  2. 将 SampleSort 模型分配给范围,将显示逻辑移到模板中;或
  3. 还有别的吗?

我认为我被 #1 所吸引,因为我发现代码比这些模板更容易阅读。将逻辑移入模板后,代码可能看起来像这样(虽然不太正确,但可以解决这个问题):

sampleSort.directive('sampleSortLegend', ['SampleSort', function(SampleSort) {
  return {
    restrict: 'E',
    controller: function($scope, $element, $attrs) {
      $scope.SampleSort = SampleSort;
    },
    template:
      'Sorted by: ' +
      '<strong ngIf="SampleSort.isByDescription()">Sample Description</strong>' + 
      '<strong ngIf="SampleSort.isByMeasurement()">{{SampleSort.elementName()}}</strong>' + 
      '<strong ngIf="SampleSort.isByDeficiency()" class="deficiency">{{SampleSort.elementName()}}</strong>' +
      ' (' +
        '<span ngIf="SampleSort.isByDescription()">{{SampleSort.isAscending() ? "A-Z" : "Z-A"}}</span>' +
        '<span ngIf="!SampleSort.isByDescription()">{{SampleSort.isAscending() ? "lowest to highest" : "highest to lowest"}}</span>' +
      ')',
  }
}]);

同样,对于这些特定的代码块,我不一定需要帮助,只是像“#1 更符合 Angular 正统观念,但你也应该......”之类的东西“=13 =]

没有理想的答案。使用你的解决方案#2(你说走向#1但实际上实现了#2),你的指令变得依赖于 SampleSort 服务,如果你不打算在不同的上下文中重用它(例如将其绑定到不同的 SampleSort,或一些继承的数据)。

将 SampleSort 分配给范围很好,但所有这些 SampleSort.isByMeasurement 方法将在每个摘要循环中调用(这在 Angular 世界中经常发生),因此请确保它们简单且快速-处理功能。

如果方法更重(或最终可能变得更重),您应该选择解决方案 #1,您可以控制观看的内容和刷新视图的时间。您应该在每个摘要上重新执行所有方法,还是应该观察特定指标(比如一些 SampleSort.lastUpdated 属性)。

或者,您也可以依赖事件:当您的 SampleSort 发生变化时,它会触发一个全局事件 ($boradcast),您的指令会捕捉并相应更新。

基本上,选择您认为更简单且易于维护的方法,并牢记每个解决方案的性能成本。