问题 过滤嵌套ng-repeat内的复杂对象
我想在嵌套的ng-repeat中过滤对象。
HTML:
<div ng-controller="MyController">
<input type="text" ng-model="selectedCityId" />
<ul>
<li ng-repeat="shop in shops">
<p ng-repeat = "locations in shop.locations | filter:search" style="display: block">
City id: {{ locations.city_id }}
<span style="padding-left: 20px; display: block;" ng-repeat="detail in locations.details | filter:item">Pin code: {{detail.pin}}</span>
</p>
</li>
</ul>
控制器:
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function ($scope) {
$scope.search = function (location) {
if ($scope.selectedCityId === undefined || $scope.selectedCityId.length === 0) {
return true;
}
if (location.city_id === parseInt($scope.selectedCityId)) {
return true;
}
};
$scope.item = function (detail) {
if ($scope.selectedCityId === undefined || $scope.selectedCityId.length === 0) {
return true;
}
if (detail.pin == parseInt($scope.selectedCityId)) {
return true;
}
};
$scope.shops =
[
{
"category_id":2,
"locations":[
{
"city_id":368,
"details": [{
"pin": 627718,
"state": 'MH'
}]
}
]
},
{
"name":"xxx",
"category_id":1,
"locations":[
{
"city_id":400,
"region_id":4,
"details": [{
"pin": 627009,
"state": 'MH'
},{
"pin": 129818,
"state": 'QA'
}]
},
]
},
];
});
这是小提琴:
http://jsfiddle.net/suCWn/210/
我想在ng-repeat中使用多个过滤器。
示例:每当用户在输入框中输入ID时。该列表应根据cityID或PinCode进行过滤。
如果用户输入'129818',它应显示129818的密码结果及其父cityID
同样,如果用户输入400,则列表应过滤并显示带有400的cityID结果及其子代码。
编辑:
更新代码 http://codepen.io/chiragshah_mb/pen/aZorMe?editors=1010]
8543
2018-05-24 13:54
起源
答案:
首先,您不得过滤具有匹配详细信息的位置。在这里使用这样的东西 search
过滤:
$scope.search = function (location) {
var id = parseInt($scope.selectedCityId);
return isNaN(id) || location.city_id === id ||
location.details.some(function(d) { return d.pin === id });
};
要显示按cityID过滤的详细信息,您必须找到父级 location
并检查是否已过滤。
$scope.item = function (detail) {
var id = parseInt($scope.selectedCityId);
return isNaN(id) || detail.pin === id || locationMatches(detail, id);
};
function locationMatches(detail, id) {
var location = locationByDetail(detail);
return location && location.city_id === id;
}
function locationByDetail(detail) {
var shops = $scope.shops;
for(var iS = 0, eS = shops.length; iS != eS; iS++) {
for(var iL = 0, eL = shops[iS].locations.length; iL != eL; iL++) {
if (shops[iS].locations[iL].details.indexOf(detail) >= 0) {
return shops[iS].locations[iL];
}
}
}
}
编辑 另一个更灵活的解决方案是从ngRepeats中删除所有过滤器,并在您调用搜索文本的ngChange的方法中进行过滤。以下是此方法的基本结构。
myApp.controller('MyController', function($scope, $http) {
var defaultMenu = [];
$scope.currentMenu = [];
$scope.searchText = '';
$http.get(/*...*/).then(function (menu) { defaultMenu = menu; } );
$scope.onSearch = function() {
if (!$scope.searchText) {
$scope.currentMenu = defaultMenu ;
}
else {
// do your special filter logic here...
}
};
});
和模板:
<input type="text" ng-model="searchText" ng-change="onSearch()" />
<ul>
<li ng-repeat="category in currentMenu">
...
</li>
</ul>
6
2018-05-24 14:12
答案:
首先,您不得过滤具有匹配详细信息的位置。在这里使用这样的东西 search
过滤:
$scope.search = function (location) {
var id = parseInt($scope.selectedCityId);
return isNaN(id) || location.city_id === id ||
location.details.some(function(d) { return d.pin === id });
};
要显示按cityID过滤的详细信息,您必须找到父级 location
并检查是否已过滤。
$scope.item = function (detail) {
var id = parseInt($scope.selectedCityId);
return isNaN(id) || detail.pin === id || locationMatches(detail, id);
};
function locationMatches(detail, id) {
var location = locationByDetail(detail);
return location && location.city_id === id;
}
function locationByDetail(detail) {
var shops = $scope.shops;
for(var iS = 0, eS = shops.length; iS != eS; iS++) {
for(var iL = 0, eL = shops[iS].locations.length; iL != eL; iL++) {
if (shops[iS].locations[iL].details.indexOf(detail) >= 0) {
return shops[iS].locations[iL];
}
}
}
}
编辑 另一个更灵活的解决方案是从ngRepeats中删除所有过滤器,并在您调用搜索文本的ngChange的方法中进行过滤。以下是此方法的基本结构。
myApp.controller('MyController', function($scope, $http) {
var defaultMenu = [];
$scope.currentMenu = [];
$scope.searchText = '';
$http.get(/*...*/).then(function (menu) { defaultMenu = menu; } );
$scope.onSearch = function() {
if (!$scope.searchText) {
$scope.currentMenu = defaultMenu ;
}
else {
// do your special filter logic here...
}
};
});
和模板:
<input type="text" ng-model="searchText" ng-change="onSearch()" />
<ul>
<li ng-repeat="category in currentMenu">
...
</li>
</ul>
6
2018-05-24 14:12
我已更新您的过滤器。问题出在你的身上 search
过滤你只检查city_id,你应该做的是:
- 检查键入的id是否为city_id
- 检查键入的id是否为a
pid
给定位置的儿童细节
类似的事情 item
过滤:
- 检查键入的id是否为a
pid
正在过滤的细节
- 检查键入的id是否为a
city_id
传入的详细信息的父位置
这里有一个 工作jsFiddle。我希望这有帮助。
2
2018-05-27 08:51
通过简单地修改 JSON
包括 city_id
对于孩子,所以你不需要循环通过它来获得父母的 city_id
,解决方案就像这样简单:
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function ($scope) {
$scope.search = function (location) {
if (!$scope.selectedCityId)
return true;
//if user's input is contained within a city's id
if (location.city_id.toString().indexOf($scope.selectedCityId) > -1)
return true;
for (var i = 0; i < location.details.length; i++)
//if user's input is contained within a city's pin
if (location.details[i].pin.toString().indexOf($scope.selectedCityId) > -1)
return true;
};
$scope.item = function (detail) {
if (!$scope.selectedCityId)
return true;
//if user's input is contained within a city's id
if (detail.city_id.toString().indexOf($scope.selectedCityId) > -1)
return true;
//if user's input is contained within a city's pin
if (detail.pin.toString().indexOf($scope.selectedCityId) > -1)
return true;
};
修改了JSON
$scope.shops=[{"category_id":2,"locations":[{"city_id":368,"details":[{"city_id":368,"pin":627718,"state":'MH'}]}]},{"name":"xxx","category_id":1,"locations":[{"city_id":400,"region_id":4,"details":[{"city_id":400,"pin":627009,"state":'MH'},{"city_id":400,"pin":129818,"state":'QA'}]},]},];});
如果直接修改了 JSON
是不可能的,你可以在此之后直接在这个控制器中修改它 $scope.shops = ...json...
声明:
for(var i=0; i<$scope.shops.length; i++)
for(var j=0, cat=$scope.shops[i]; j<cat.locations.length; j++)
for(var k=0, loc=cat.locations[j]; k<loc.details.length; k++)
loc.details[k].city_id=loc.city_id;
工作小提琴:
http://jsfiddle.net/87e314a0/
1
2018-06-01 22:38
我试图让解决方案更容易理解:
index.html:
<div ng-controller="MyController">
<input type="text" ng-model="search.city_id" />
<ul>
<li ng-repeat="shop in shops">
<p ng-repeat = "locations in shop.locations | filter:search.city_id" style="display: block">
City id: {{ locations.city_id }}
<span style="padding-left: 20px; display: block;" ng-repeat="detail in locations.details | filter:item">Pin code: {{detail.pin}}</span>
</p>
</li>
</ul>
</div>
app.js:
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function ($scope) {
$scope.shops =
[
{
"category_id":2,
"locations":[
{
"city_id":368,
"details": [{
"pin": 627718,
"state": 'MH'
}]
}
]
},
{
"name":"xxx",
"category_id":1,
"locations":[
{
"city_id":400,
"region_id":4,
"details": [{
"pin": 627009,
"state": 'MH'
},{
"pin": 129818,
"state": 'QA'
}]
},
]
},
];
});
这是小提琴:
mySolution
1
2018-06-02 15:48