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技能......任何帮助?

+0

您是否尝试过使用'orderBy'过滤器来执行排序,要么在'ngRepeat'中,要么在您的控制器中? – 2014-09-30 16:46:10

+0

我可以在上面粘贴的数组上使用orderBy,但是我无法构造它。这是我面临的问题。 – enguerranws 2014-10-01 08:14:03

+0

你可以发布你想要的当前数据结构和最终结果吗? – 2014-10-01 15:50:34

我最后问一个朋友,谁是一个很好的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(); 

Live Demo

+0

我想过了,我已经知道我可以使用jQuery $ .map()以更简单的方式实现这一点。但我不想用另一个js库:)谢谢你! – enguerranws 2014-10-04 11:27:52