AngularJS:检查对象中是否存在键/值并构建对象数组
以下是我正在使用的服务的一种方法。它从项目中找到所有收入(与此问题相关:Angular service calling another service)并创建一个新的对象数组。AngularJS:检查对象中是否存在键/值并构建对象数组
我希望这个数组的对象能够在年份和三个月中对收入进行排序,所以我可以在视图中轻松地循环查看(使用ng-repeat)。
我现在的数据(由Incomes.buildAndGetIncomes()
返回,你可以看到如下图):
[
{
"projectName":"Deuxième test",
"clientName":"Deuxième client",
"typeIncome":"Accompte",
"amount":1000,
"date":"2014-09-10",
"notes":"Chèque/LDD",
"trim":"third",
"year":"2014"
},
{
"projectName":"efzefze",
"clientName":"zfezefzef",
"typeIncome":"Accompte",
"amount":30,
"date":"2014-09-10",
"notes":"fzefzef",
"trim":"third",
"year":"2014"
},
{
"projectName":"Nouveau test",
"clientName":"Nouveau client",
"typeIncome":"Accompte",
"amount":16,
"date":"2014-09-19",
"notes":"CC",
"trim":"third",
"year":"2014"
},
{
"projectName":"Nouveau projet",
"clientName":"Nouveau client",
"typeIncome":"Accompte",
"amount":1200,
"date":"2014-05-17",
"notes":"Chèque cc",
"trim":"second",
"year":"2014"
},
{
"projectName":"Projet test",
"clientName":"Client test",
"typeIncome":"Accompte",
"amount":1500,
"date":"2014-01-15",
"notes":"Chèque cc",
"trim":"first",
"year":"2014"
},
{
"projectName":"Deuxième test",
"clientName":"Deuxième client",
"typeIncome":"Reliquat",
"amount":4500,
"date":"2014-09-27",
"notes":"Virement",
"trim":"third",
"year":"2014"
},
{
"projectName":"efzefze",
"clientName":"zfezefzef",
"typeIncome":"Reliquat",
"amount":8,
"date":"2014-09-05",
"notes":"zefzefzef",
"trim":"third",
"year":"2014"
},
{
"projectName":"Nouveau test",
"clientName":"Nouveau client",
"typeIncome":"Reliquat",
"amount":7,
"date":"2014-09-27",
"notes":"LDD",
"trim":"third",
"year":"2014"
}
]
的数据结构,我想:
[
{
year: 2014,
trim: [
{
name : 'first',
content : [
// some content
]
},
{
name : 'second',
content : [
// some content
]
}
]
},
{
year: 2013,
trim: [
{
name : 'first',
content : [
// some content
]
}
]
}
]
这里是我现在使用的方法:
self.trimestral = function(){
var deferred = $q.defer();
self.buildAndGetIncomes().then(function(result) {
var trimestral = [];
var incomes = result;
angular.forEach(incomes, function(income, i){
var year = income.year,
trim = income.trim,
newTrim = {},
newTrimContent = {};
if(i === 0){
newTrim.year = year;
newTrim.trim = [];
newTrimContent ={};
newTrimContent.name = trim;
newTrimContent.content = [];
newTrimContent.content.push(income);
trimestral.push(newTrim);
console.log(trimestral);
trimestral[0].trim.push(newTrimContent);
}
else {
var maxLength = incomes.length;
for (var h = 0; h<maxLength; h++){
if(trimestral[h].year === year){
for (var j = 0; j<trimestral[h].trim.length; j++){
console.log(h,j,trimestral[h].trim[j].name === trim);
if(trimestral[h].trim[j].name === trim){ // trimester already exists
trimestral[h].trim[j].content.push(income);
}
else {// trimester doesn't exist, create it
var createTrim = {};
createTrim.name = trim;
createTrim.content = [];
createTrim.content.push(income);
trimestral[h].trim.push(newTrimContent);
}
}
}
else {
newTrim.year = year;
newTrim.trim = [];
newTrimContent ={};
newTrimContent.name = trim;
newTrimContent.content = [];
newTrimContent.content.push(income);
trimestral.push(newTrim);
console.log(trimestral);
trimestral[0].trim.push(newTrimContent);
}
}
}
});
deferred.resolve(trimestral);
});
return deferred.promise;
};
此代码按假定的方式工作,它检查我们是否在fi这个循环的第一个索引,并且推动该学期的年/三学期/内容。这个结构是可以的。
现在我的问题是我需要检查一年是否已经存在,然后检查该孕期是否存在于那一年的对象中,以构建一个像上面粘贴的对象数组。
我尝试了很多方法来做到这一点,但它似乎太难以我的JS技能......任何帮助?
我最后问一个朋友,谁是一个很好的Web开发人员帮我一下。他让我在这两个步骤中做到这一点:构造对象,然后,以我需要的方式格式化它。
所以我这样做:
self.trimestral = function(){
var deferred = $q.defer();
var global = [];
self.buildAndGetIncomes().then(function(result) {
var trimestral = {};
var incomes = result;
// First loop, construct the object
angular.forEach(incomes, function(income, i){
var year = income.year,
trim = income.trim,
newTrim = {},
newTrimContent = {};
if(trimestral[year] === undefined){
trimestral['year' , year] = {};
}
if(trimestral[year][trim] === undefined) {
trimestral[year][trim] = [];
}
trimestral[year][trim].push(income);
});
deferred.resolve(global);
// Second loop, format the data
for (prop in trimestral) {
newYear = {};
newYear.name = prop;
newYear.content = [];
for (trim in trimestral[prop]){
newTrim = {};
newTrim.name = trim;
newTrim.content = [];
newTrim.content = trimestral[prop][trim];
newYear.content.push(newTrim);
}
global.push(newYear);
}
});
return deferred.promise;
};
我猜这可能是清洁的,但它的工作原理和它的更简单的比我的预期。
这当然可以使用几个循环,但代码将很难遵循。如果您可以带上另一个库,请考虑underscore.js。有了它,你可以做这样的事情......
var trimestral = _(incomes).chain()
.groupBy('year')
.map(function (items, year) {
return {
year: year,
trim: _(items).chain()
.groupBy('trim')
.map(function(content, trimester) {
return {
trim: trimester,
content: content
};
})
.sortBy(function(i) {
var trimesters = {
first: 1,
second: 2,
third: 3
};
return trimesters[i.trim];
}).value()
};
})
.sortBy('year')
.value();
我想过了,我已经知道我可以使用jQuery $ .map()以更简单的方式实现这一点。但我不想用另一个js库:)谢谢你! – enguerranws 2014-10-04 11:27:52
您是否尝试过使用'orderBy'过滤器来执行排序,要么在'ngRepeat'中,要么在您的控制器中? – 2014-09-30 16:46:10
我可以在上面粘贴的数组上使用orderBy,但是我无法构造它。这是我面临的问题。 – enguerranws 2014-10-01 08:14:03
你可以发布你想要的当前数据结构和最终结果吗? – 2014-10-01 15:50:34