我的目标是应用设置为循环对象属性的格式化过滤器。
获取这个对象数组:
[
{
"value": "test value with null formatter",
"formatter": null,
},
{
"value": "uppercase text",
"formatter": "uppercase",
},
{
"value": "2014-01-01",
"formatter": "date",
}
]
我想写的模板代码是:
<div ng-repeat="row in list">
{{ row.value | row.formatter }}
</div>
我希望看到这个结果:
test value with null formatter
UPPERCASE TEXT
Jan 1, 2014
但是很可能这个代码会抛出一个错误:
Unknown provider: row.formatterFilterProvider <- row.formatterFilter
我无法想象如何解析{{}}中的“formatter”参数;有谁可以帮助我?
请参阅plunkr http://plnkr.co/edit/YnCR123dRQRqm3owQLcs?p=preview
答案 0 :(得分:57)
|
是一个角度构造,它找到具有该名称的已定义过滤器并将其应用于左侧的值。我认为您需要做的是创建一个过滤器,将过滤器 name 作为参数,然后调用适当的过滤器(fiddle)(改编自M59的代码):
<强> HTML: 强>
<div ng-repeat="row in list">
{{ row.value | picker:row.formatter }}
</div>
<强> 使用Javascript: 强>
app.filter('picker', function($filter) {
return function(value, filterName) {
return $filter(filterName)(value);
};
});
感谢@ karlgold的评论,这是一个支持参数的版本。第一个示例直接使用add
过滤器向现有数字添加数字,第二个示例使用useFilter
过滤器按字符串选择add
过滤器并将参数传递给它{{3} }:
<强> HTML: 强>
<p>2 + 3 + 5 = {{ 2 | add:3:5 }}</p>
<p>7 + 9 + 11 = {{ 7 | useFilter:'add':9:11 }}</p>
<强> 使用Javascript: 强>
app.filter('useFilter', function($filter) {
return function() {
var filterName = [].splice.call(arguments, 1, 1)[0];
return $filter(filterName).apply(null, arguments);
};
});
答案 1 :(得分:13)
我喜欢这些答案背后的概念,但不认为它们提供了最灵活的解决方案。
我真正想做的事情并且我确信一些读者会有同样的感受,就是能够动态传递过滤器表达式,然后评估并返回适当的结果。
因此,单个自定义过滤器将能够处理以下所有内容:
{{ammount | picker:'currency:"$":0'}}
{{date | picker:'date:"yyyy-MM-dd HH:mm:ss Z"'}}
{{name | picker:'salutation:"Hello"'}}
//应用其他自定义过滤器
我提出了以下代码,它将$interpolate
服务用于我的自定义过滤器。请参阅jsfiddle:
<强>的Javascript 强>
myApp.filter('picker', function($interpolate ){
return function(item,name){
var result = $interpolate('{{value | ' + arguments[1] + '}}');
return result({value:arguments[0]});
};
});
答案 2 :(得分:5)
使其工作的一种方法是使用函数进行绑定并在该函数中进行过滤。这可能不是最佳方法: Live demo (click).
<div ng-repeat="row in list">
{{ foo(row.value, row.filter) }}
</div>
<强> JavaScript的:强>
$scope.list = [
{"value": "uppercase text", "filter": "uppercase"}
];
$scope.foo = function(value, filter) {
return $filter(filter)(value);
};
答案 3 :(得分:0)
我的需求略有不同,因此对上述答案进行了一些修改($interpolate
解决方案达到了同一目标,但仍然有限):
angular.module("myApp").filter("meta", function($filter)
{
return function()
{
var filterName = [].splice.call(arguments, 1, 1)[0] || "filter";
var filter = filterName.split(":");
if (filter.length > 1)
{
filterName = filter[0];
for (var i = 1, k = filter.length; i < k; i++)
{
[].push.call(arguments, filter[i]);
}
}
return $filter(filterName).apply(null, arguments);
};
});
用法:
<td ng-repeat="column in columns">{{ column.fakeData | meta:column.filter }}</td>
数据:
{
label:"Column head",
description:"The label used for a column",
filter:"percentage:2:true",
fakeData:-4.769796600014472
}
(percentage
是一个自定义过滤器,可以构建number
)
答案 4 :(得分:0)
这篇文章归功于Jason Goemaat。
以下是我如何使用它。
$scope.table.columns = [{ name: "June 1 2015", filter: "date" },
{ name: "Name", filter: null },
] etc...
<td class="table-row" ng-repeat="column in table.columns">
{{ column.name | applyFilter:column.filter }}
</td>
app.filter('applyFilter', [ '$filter', function( $filter ) {
return function ( value, filterName ) {
if( !filterName ){ return value; } // In case no filter, as in NULL.
return $filter( filterName )( value );
};
}]);
答案 5 :(得分:0)
我通过添加检查过滤器是否存在来改进@Jason Goemaat的答案,如果不是默认返回第一个参数:
.filter('useFilter', function ($filter, $injector) {
return function () {
var filterName = [].splice.call(arguments, 1, 1)[0];
return $injector.has(filterName + 'Filter') ? $filter(filterName).apply(null, arguments) : arguments[0];
};
});
答案 6 :(得分:0)
较新版本的ng-table允许基于列配置创建动态表(ng-dynamic-table)。格式化日期字段就像在列数组中将字段值添加到字段值一样简单。
鉴于
{
"name": "Test code",
"dateInfo": {
"createDate": 1453480399313
"updateDate": 1453480399313
}
}
columns = [
{field: 'object.name', title: 'Name', sortable: 'name', filter: {name: 'text'}, show: true},
{field: "object.dateInfo.createDate | date :'MMM dd yyyy - HH:mm:ss a'", title: 'Create Date', sortable: 'object.dateInfo.createDate', show: true}
]
<table ng-table-dynamic="controller.ngTableObject with controller.columns" show-filter="true" class="table table-condensed table-bordered table-striped">
<tr ng-repeat="row in $data">
<td ng-repeat="column in $columns">{{ $eval(column.field, { object: row }) }}</td>
</tr>
</table>
答案 7 :(得分:0)
我最终做了一些更粗糙的事情,但更少涉及:
<强> HTML:强>
使用三元运算符检查是否为该行定义了过滤器:
ng-bind="::data {{row.filter ? '|' + row.filter : ''}}"
<强> JS:强>
在Javascript的数据数组中添加过滤器:
, {
data: 10,
rowName: "Price",
months: [],
tooltip: "Price in DKK",
filter: "currency:undefined:0"
}, {
答案 8 :(得分:0)
这就是我使用的(Angular Version 1.3.0-beta.8 accidental-haiku)。
此过滤器允许您使用带或不带过滤器选项的过滤器。
applyFilter 将检查过滤器是否存在于Angular中,如果过滤器不存在,那么带有过滤器名称的错误消息将在浏览器控制台中如此...
以下过滤器不存在:greenBananas
使用 ng-repeat 时,某些值将是未定义的。 applyFilter 将通过软故障处理这些问题。
app.filter( 'applyFilter', ['$filter', '$injector', function($filter, $injector){
var filterError = "The following filter does not exist: ";
return function(value, filterName, options){
if(noFilterProvided(filterName)){ return value; }
if(filterDoesNotExistInAngular(filterName)){ console.error(filterError + "\"" + filterName + "\""); return value; }
return $filter(filterName)(value, applyOptions(options));
};
function noFilterProvided(filterName){
return !filterName || typeof filterName !== "string" || !filterName.trim();
}
function filterDoesNotExistInAngular(filterName){
return !$injector.has(filterName + "Filter");
}
function applyOptions(options){
if(!options){ return undefined; }
return options;
}
}]);
然后你使用你想要的过滤器,可能有也可能没有选项。
// Where, item => { name: "Jello", filter: {name: "capitalize", options: null }};
<div ng-repeat="item in items">
{{ item.name | applyFilter:item.filter.name:item.filter.options }}
</div>
或者,您可以在构建表时使用单独的数据结构。
// Where row => { color: "blue" };
// column => { name: "color", filter: { name: "capitalize", options: "whatever filter accepts"}};
<tr ng-repeat="row in rows">
<td ng-repeat="column in columns">
{{ row[column.name] | applyFilter:column.filter.name:column.filter.options }}
</td>
</tr>
如果您发现需要传递更具体的值,可以添加更多这样的参数......
// In applyFilter, replace this line
return function(value, filterName, options){
// with this line
return function(value, filterName, options, newData){
// and also replace this line
return $filter(filterName)(value, applyOptions(options));
// with this line
return $filter(filterName)(value, applyOptions(options), newData);
然后在HTML中,您的过滤器也需要行对象
中的密钥// Where row => { color: "blue", addThisToo: "My Favorite Color" };
// column => { name: "color", filter: { name: "capitalize", options: "whatever filter accepts"}};
<tr ng-repeat="row in rows">
<td ng-repeat="column in columns">
{{ row[column.name] | applyFilter:column.filter.name:column.filter.options:row.addThisToo }}
</td>
</tr>