我在这篇文章的接受答案中找到了我问题的一半答案。 How do I filter an array with AngularJS and use a property of the filtered object as the ng-model attribute?
我想知道是否可以通过另一个会创建这些对象数组的字段进行过滤,然后使用该数组中两个不同对象的值。
类似的东西......(带有ng-show =“data.Options.HasMap”的td)
<tbody>
<tr ng-repeat="row in data.Rows">
<td ng-repeat="col in row.Columns" ng-show="{{col.Visible}}">
{{ col.Value }}
</td>
<td ng-show="data.Options.HasMap" ng-repeat="hidden in row.Columns | filter:{Visible:false} track by $index">
{{hidden.Value | filter:{HeaderText:'Latitude'}}} , {{hidden.Value | filter:{HeaderText:'Longitude'}}}
</td>
<td ng-show="data.Options.HasSuppression">
</td>
<td ng-show="data.Options.HasAction">
</td>
</tr>
</tbody>
我的Json文件有一系列列,如...
"Columns": [{
"HeaderText": "R1 - F1",
"Value": "data1",
"Visible": true
},...
我希望将列拉出Visible:false,然后选择具有特定HeaderTexts的两个不同对象的值。
对不起,如果这听起来很混乱。任何帮助,将不胜感激。我对Angular很新,只是想弄清楚事情!
修改。 只是要指出我可以得到我需要的一个列对象。
<td ng-show="data.Options.HasMap" ng-repeat="hidden in row.Columns | filter:{HeaderText:'Latitude'} track by $index"> {{ hidden.Value }} </td>
但我真的需要Latitude和Longitude列对象来创建一个带有查询字符串变量的url。
我也试过......
<td ng-show="data.Options.HasMap">
{{ row.Columns.Value | filter:{HeaderText:'Latitude'} }} , {{ row.Columns.Value | filter:{HeaderText:'Longitude'} }}
</td>
答案 0 :(得分:0)
此行的值为hidden.Value
(上例中为"R1 - F1"
),并对其应用过滤器{ HeaderText: 'Latitude'}
:
{{hidden.Value | filter:{HeaderText:'Latitude'}}} , {{hidden.Value | filter:{HeaderText:'Longitude'}}}
您尝试使用针对对象数组的过滤器过滤字符串;这将只返回一个空数组,肯定不是你想要的。从你的例子中不清楚经度&#39;经度&#39;和纬度&#39;属性已定义。也许你想再次过滤列列表?就像是:
我不完全确定您要尝试做什么,请解释定义纬度/经度属性的位置。
另一件需要关注的是自定义过滤器,这些也可能有所帮助。看看Using filter to create array, then using that array to filter ng-options
修改强>
要使用HeaderText =&#34; Latitude&#34;和HeaderText =&#34;经度&#34;获取两列,您可以执行以下操作:
<span ng-repeat="col in row.Columns | filter:{HeaderText: "Latitude"}>
如果这不符合您的需求,请查看自定义过滤器。这是一个示例,可以根据您传入的任何值匹配标题文本进行过滤:
app.filter('filterByHeaderText', function() {
return function(input, headerText) {
// Input is the array to be filtered,
input = input || [];
headerText = headerText || [];
var output = [];
for (var i = 0; i < input.length; i++) {
for (var j = 0; j < headerText.length; j++) {
// If input matches any of the headerText, then add it to the list
if (input[i].headerText.indexOf(headerText[j].trim()) >= 0) {
output.push(input[i]);
break;
}
}
}
return output;
};
})
然后可以像这样使用此过滤器:
<span ng-repeat="item in row.Columns | filterByHeaderText: ['Latitude', 'Longitude']">
答案 1 :(得分:0)
对不起,这是我的第一个答案。我像这样过滤数组的自定义过滤器。 假设我们有这样的JSON对象数组:
var myArray=[{prop1:"val1", prop2:"val2", ...}, ...]
搜索参数在property name : property value
对中定义,其结构应如下所示:
var examplePairs={
prop1:"val1",
prop2:["val2", "val3"],
prop4:{eqStart:true, eqEnd:false, iStart:123, iEnd: 321}
};
此示例在数组中搜索属性prop1
的值为val1
且属性prop2
的值为val2
或val3
且属性为prop3
的所有匹配项来自区间[123,321>
注意:对于区间搜索,数组中对象内的数据必须是数字(不应该用引号定义)。
评论中有解释。 对于您的特定情况调用过滤器,如下所示:
{{ pairs={HeaderText:['Latitude', 'Longitude'], Visible:true} }}
<span ng-repeat="col in row.Columns | jsonArrayMultiFilter : pairs >
或者从控制器调用过滤器,如下所示:
var pairs={HeaderText:['Latitude', 'Longitude'], Visible:true}
$scope.row.Columns=$filter('jsonArrayMultiFilter')($scope.row.Columns, pairs);
自定义过滤器代码:
.filter('jsonArrayMultiFilter', function() {
return function(x, pairs) {
//filters
//pairs = property:value pairs
//in case same properties can have multiple value pairs should be defined as followed
// {property:[value1, value2]}
//if value of property fits inside interval it should be defined as followed
// {property:{eqStart:true, eqEnd:false, iStart:"start of interval", iEnd:"end of interval"}}
// if value in data is string it searches if string contains searched value
var keys=Object.keys(pairs);
//console.log(keys);
var newData=[];
var counter, tempCount, expression;
for (var i=0;i<x.length;i++){
//iterate data then apply multiple filters
//set counter value 0 for each itteration trough data
//if all pairs satisfies conditions counter should equal (keys.length - 1)
//for effitiency when condition is not satisfied loop should be broken on first fail
counter=0;
for (var j=0; j < keys.length; j++ ){
//iterrate through pairs
if (pairs[keys[j]].constructor === Array){
//if property has multiple values itterate trough values
tempCount=counter;
for (var k=0; k < pairs[keys[j]].length; k++){
//create regexp to perform case insensitive search
var rExp = new RegExp(pairs[keys[j]][k], "i");
//if value is a string expression searches the string if it is number finds exact match
expression=(typeof x[i][keys[j]] == 'string' || x[i][keys[j]] instanceof String)?x[i][keys[j]].search(rExp)>-1:x[i][keys[j]]==pairs[keys[j]][k];
if (expression){
counter++;
}
}
if (tempCount==counter){
//break itteration because one condition isn't satisfied for data x[i]
break;
}
}else{
//if not array but is object and property['iStart'] is not null and not undefined check if value is from interval
if( typeof pairs[keys[j]]['iStart'] !== 'undefined' && pairs[keys[j]]['iStart'] !== null ){
// if value is from interval
var leftLimit=pairs[keys[j]]['eqStart']?x[i][keys[j]] >= pairs[keys[j]]['iStart']:x[i][keys[j]] > pairs[keys[j]]['iStart'];
var rightLimit=pairs[keys[j]]['eqEnd']?x[i][keys[j]] <= pairs[keys[j]]['iEnd']:x[i][keys[j]] < pairs[keys[j]]['iEnd'];
if (leftLimit && rightLimit){
counter++;
}
else{
//break itteration because one condition isn't satisfied for data x[i]
break;
}
}else{
//create regexp to perform case insensitive search
var rExp = new RegExp(pairs[keys[j]], "i");
//if value is a string expression searches the string if it is number finds exact match
expression=(typeof x[i][keys[j]] == 'string' || x[i][keys[j]] instanceof String)?x[i][keys[j]].search(rExp)>-1:x[i][keys[j]]==pairs[keys[j]];
//if property has one value make comparsion
if (x[i][keys[j]]==pairs[keys[j]]){
counter++;
}
else {
//break itteration because condition isn't satisfied for data x[i]
break;
}
}
}
//if all conditions are satisfied
if (counter >= keys.length){
newData.push(x[i]);
}
}
}
return newData;
};
})