我有一个这样的对象:
var object = {
'Shirts': {
'Size': [
{name: 'Large'},
{name: 'Medium'}
],
'Color': [
{name: 'Blue', image: 'imageURL'},
{name: 'Red', image: 'imageURL'}
],
'_attributes': [
{position: 1}
]
},
'Pants': {
'Size': [
{name: 'Large'},
{name: 'Medium'}
],
'_attributes': [
{position: 0}
]
}
}
我试图让ng-repeat根据位置按升序或降序对对象结构进行排序。
_attributes
键也有可能不存在,在这种情况下,该位置应该位于其他有位置的位置之后。
我应该在ng-repeat中加入什么?
<div ng-repeat="(key, option) in object | orderBy:'WHATSHOULD BE HERE?'">
{{key}}
</div>
上面只会打印出来:
Pants
Shirts
答案 0 :(得分:0)
编辑添加了一个正在运行的过滤器版本,老实说,看看数据是否可以从服务层更好地组织,或者在服务中处理这种清理,而不是让它一直在过滤器中运行。
angular
.module('myApp', [])
.controller('MyCtrl', function(){
this.object = {
'Shirts': {
'Size': [
{name: 'Large'},
{name: 'Medium'}
],
'Color': [
{name: 'Blue', image: 'imageURL'},
{name: 'Red', image: 'imageURL'}
],
'_attributes': [
{position: 1}
]
},
'Pants': {
'Size': [
{name: 'Large'},
{name: 'Medium'}
],
'_attributes': [
{position: 0}
]
}
}
})
.filter('myFilter', function(){
return function(input){
var newArray = [];
var extra = [];
if(!input) return newArray;
for(prop in input)
{
input[prop].displayName = prop;
if(input.hasOwnProperty(prop)){
if(input[prop]._attributes){
newArray[input[prop]._attributes[0].position] = input[prop];
}
else{
extra.push(input[prop])
}
}
}
return newArray.concat(extra)
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl as myCtrl">
<div ng-repeat="datum in myCtrl.object | myFilter">
{{datum.displayName|json}}
</div>
</div>
OrderBy过滤器用于处理数组或其他“集合”(参见参数部分)https://docs.angularjs.org/api/ng/filter/orderBy JS中的对象是无序集合,因此尽管浏览器对它非常一致,但它没有固有的顺序,规格没有很好地定义应该使用什么订单。这就是说你可以很容易地制作一个自定义过滤器,只需要在过滤器中做任何你想要做的事情,无论什么类型的对象被传递到你的过滤器。要定义一个自定义过滤器,它只是一个新函数,它接受一些输入,在这种情况下是对象,并且在这种情况下返回一个新项目可能会返回一个数组,用于重复的ng-repeat并且数组有一个根据您如何推入对象或以其他方式填充数组来修复排序。
通常,过滤器定义如下:
.filter('myFilter', function(/*injectables here like $http*/){
return function(input/*, other args here if needed input is object in your case*/) {
//Do stuff in here to order the object how you want or put it in an array
var retObj = {newStuff:'hello', oldStuff: input};
return retObj;
}
})
用法如
<div ng-repeat="(key, option) in object | myFilter">
{{key}}
</div>
答案 1 :(得分:0)
如果你想使用orderBy
,filter
,你的样本中的将对象更改为数组,并将此(
array
)更好地工作 比object
。
var app = angular.module("app", []);
app.controller("ctrl", ["$scope", "$http", function($scope, $http) {
var object = {
'Shirts': {
'Size': [{
name: 'Large'
},
{
name: 'Medium'
}
],
'Color': [{
name: 'Blue',
image: 'imageURL'
},
{
name: 'Red',
image: 'imageURL'
}
],
'_attributes': [{
position: 1
}]
},
'Pants': {
'Size': [{
name: 'Large'
},
{
name: 'Medium'
}
],
'_attributes': [{
position: 0
}]
}
}
var convertToArray = function(singleObject) {
var items = [];
for (var key in singleObject) {
var newObject = {
name: key,
options: object[key]
}
items.push(newObject);
}
return items;
}
$scope.items = convertToArray(object);
}]);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<button ng-click="reverse = !reverse">reverse items by name</button>
<ul>
<li ng-repeat="item in items | orderBy:'name':reverse">
<h3>{{item.name}}</h3>
<ul>
<li ng-if="item.options.Color"><b>Colors</b></li>
<li ng-repeat="color in item.options.Color">
{{color.name}}
</li>
<li><b>Sizes</b></li>
<li ng-repeat="size in item.options.Size">
{{size.name}}
</li>
</ul>
</li>
</ul>
</div>
&#13;