在 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}})',
}
}]);
这给了我想要的结果,除了它是完全非交互的,因为这三个范围属性永远不会改变。要解决这个问题,最好是:
- 在控制器中设置一个 $watch 以在我的 SampleSort 的关键响应发生变化时更新范围;
- 将 SampleSort 模型分配给范围,将显示逻辑移到模板中;或
- 还有别的吗?
我认为我被 #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
),您的指令会捕捉并相应更新。
基本上,选择您认为更简单且易于维护的方法,并牢记每个解决方案的性能成本。
我正在寻找合适的位置来放置一些与表示相关的逻辑 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}})',
}
}]);
这给了我想要的结果,除了它是完全非交互的,因为这三个范围属性永远不会改变。要解决这个问题,最好是:
- 在控制器中设置一个 $watch 以在我的 SampleSort 的关键响应发生变化时更新范围;
- 将 SampleSort 模型分配给范围,将显示逻辑移到模板中;或
- 还有别的吗?
我认为我被 #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
),您的指令会捕捉并相应更新。
基本上,选择您认为更简单且易于维护的方法,并牢记每个解决方案的性能成本。