在Angular控制器中设置监视与更复杂的模板

时间:2015-02-09 21:11:58

标签: angularjs angularjs-directive angularjs-scope angularjs-controller

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

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

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

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. 在我的SampleSort的关键响应更改时,在控制器中设置 $ watch 以更新范围;
  2. 将SampleSort模型分配到范围,将显示逻辑移动到模板;或
  3. 别的什么?
  4. 我认为我被#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正统,但你也应该......”

1 个答案:

答案 0 :(得分:1)

没有理想的答案。使用你的解决方案#2(你说要吸引#1但实际上已经实现了#2),你的指令依赖于SampleSort服务,如果你不打算在不同的环境中重用它,这很好(例如将它绑定到一个不同的SampleSort或一些继承的数据)。

将SampleSort分配给范围很好,但是每个摘要周期都会调用所有这些SampleSort.isByMeasurement方法(这在Angular世界中经常发生),因此请确保它们是微不足道的快速处理函数。

如果方法较重(或最终可能成为),您应该选择解决方案#1来控制您观看的内容以及刷新视图的时间。您是否应该在每个摘要上重新执行所有方法,或者您是否应该查看特定指标(如某些SampleSort.lastUpdated属性)。

或者,您也可以依赖事件:当您的SampleSort发生更改时,它将触发您的指令将捕获并相应更新的全局事件($boradcast)。

基本上,为您提供更简单,易于维护的内容,并牢记每个解决方案的性能成本。