我试图了解如何使用AngularJS完成条件格式化。
我的场景,我有一个表格,里面有很多这样的值:
<tr ng-repeat='r in row'>
<td>{{r.valueA | number:0}}</td>
<td>{{r.valueB | number:0}}</td>
<td>{{r.valueA - r.valueB | number:0}}</td>
<td>{{total.valueA - r.valueA | number:0}}</td>
<td>{{total.valueA - (r.valueA - r.valueB | number:0)}}</td>
</tr>
我想要发生的是这些单元格在数字为负数时将文本更改为红色。
以下是我的尝试:
A)使用ng-class
指令路线:
<tr ng-repeat='r in row'>
<td ng-class="{'text-red':r.valueA < 0}">{{r.valueA | number:0}}</td>
<td ng-class="{'text-red':r.valueB < 0}">{{r.valueB | number:0}}</td>
<td ng-class="{'text-red':(r.valueA - r.valueB) < 0}">{{r.valueA - r.valueB | number:0}}</td>
<td ng-class="{'text-red':(total.valueA - r.valueA) < 0}">{{total.valueA - r.valueA | number:0}}</td>
<td ng-class="{'text-red':(total.valueA - (r.valueA - r.valueB)) < 0}">{{total.valueA - (r.valueA - r.valueB) | number:0}}</td>
</tr>
......它有效,但有很多不必要的打字。当然有更好的方法。
B)自定义过滤器但无法使其正常工作:
myApp.filter('numberVariance',
['$filter',
function (filter) {
var numberFilter = filter('number');
return function (amount, fractionDigits) {
if (value === "0") {
return "-";
}
var value = numberFilter(amount, fractionDigits);
if (amount < 0)
return "<span class='text-red'>" + value + "</span>";
return value;
};
}]);
...这会转义返回的HTML字符串。我宁愿找到一个不使用ng-html-bind
或“不安全”字符串的解决方案。
C)自定义指令。这感觉它是最合适的,但我不能让它工作:
myApp.directive('varianceValue', function () {
return {
restrict: 'A',
link: function (scope, el, attr) {
$(el).toggleClass("text-red", ($(el).text().indexOf('-') > -1));
},
}
});
...这在首次加载时工作正常,但不会在值更新时切换类。
答案 0 :(得分:1)
您可以使用angular ng-class
指令,在计算值为负时添加适当的类。
这是最干净的方法(使用角度哲学)因为:
它使用绑定到计算变量的CSS类
此解决方案的每个部分都有不同的作用(css for the 视觉效果,控制班级的真/假值)
它灵活,易于修改,可以轻松扩展(添加 更多的类,根据颜色获取颜色的不同逻辑 价值等)
计算在控制器中执行
至于额外输入:可以通过添加额外的(嵌套的)ng-repeat来为每行生成<td>
来进一步减少。
一个工作示例:
HTML:
<style>
.red {
color: red
}
</style>
<span ng-app="myApp" ng-controller="mainCtrl">
<table>
<tr ng-repeat='r in row'>
<td ng-class="{ red: isRed(getColumnVal(r, 1)) }">
{{getColumnVal(r, 1)}}
</td>
<td ng-class="{ red: isRed(getColumnVal(r, 2)) }">
{{getColumnVal(r, 2)}}
</td>
<td ng-class="{ red: isRed(getColumnVal(r, 3)) }">
{{getColumnVal(r, 3)}}
</td>
</tr>
</table>
</span>
JS:
var myApp = angular.module('myApp',[]);
myApp.controller('mainCtrl', ['$scope', function ($scope) {
// the array of objects*
$scope.row = [
{
valueA: 1,
valueB: 2
},
{
valueA: 3,
valueB: 4
}
];
// returns the value for the given object* and the given table column
$scope.getColumnVal = function (o, col) {
var columnVal = 0;
switch (col) {
case 1:
columnVal = o.valueA
break;
case 2:
columnVal = o.valueB;
break;
case 3:
columnVal = o.valueA - o.valueB;
break;
default:
columnVal = 0;
}
return columnVal;
};
// returns true if the given val is smaller than zero, else returns false
$scope.isRed = function (val) {
var isRed = false;
if (val < 0) {
isRed = true;
}
return isRed;
};
}]);
进一步减少打击:
通过添加额外的<td>
ng-repeat
HTML:
<style>
.red {
color: red
}
</style>
<span ng-app="myApp" ng-controller="mainCtrl">
<table>
<tr ng-repeat='r in row'>
<td ng-repeat='c in columns' ng-class="{ red: isRed(getColumnVal(r, c)) }">
{{getColumnVal(r, c)}}
</td>
</tr>
</table>
</span>
并根据您的需要向控制器添加以下定义列的语句:
$scope.columns = [1, 2, 3]; // This is for 3 columns, extend to your needs
答案 1 :(得分:1)
使用$ timeout给出Angular时间来评估表达式,你的指令应该可以正常工作。
工作example
app.directive('varianceValue', function ($timeout) {
return {
restrict: 'A',
link: function (scope, el, attr) {
$timeout(function(){
$(el).toggleClass("text-red", ($(el).text().indexOf('-') > -1));
},0);
},
}
});
<强> HTML 强>
<table>
<tbody>
<tr ng-repeat="r in row">
<td variance-value>{{r.valueA | number:0}}</td>
<td variance-value>{{r.valueB | number:0}}</td>
<td variance-value>{{r.valueA - r.valueB | number:0}}</td>
<td variance-value>{{total.valueA - r.valueA | number:0}}</td>
<td variance-value>{{total.valueA - (r.valueA - r.valueB | number:0)}}</td>
</tr>
</tbody>
</table>
答案 2 :(得分:0)
我会使用ng-class,但是根据应用程序的设置方式,将逻辑拉出到控制器/服务中描述性命名的函数中。
答案 3 :(得分:0)
以下是我最终选择的解决方案。谢谢大家的贡献。
myApp.directive('varianceValue', [ function () {
return {
restrict: 'A',
link: function (scope, el, attr) {
scope.$watch(
function () { return el.text() },
function () { $(el).toggleClass("text-red", ($(el).text().indexOf('-') > -1)); }
);
},
}
}]);
我弄乱了各种$ watch值,其中大多数都让应用程序爬行,但上面的版本保持强大。