2014-09-30 1 views
0

Вот метод службы, которую я использую. Он находит все доходы от проектов (связанных с этим вопросом: 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', либо внутри вашего контроллера? –

+0

Я мог бы использовать orderBy для массива, как я вставил выше, но я не могу его построить. Это проблема, с которой я столкнулся. – enguerranws

+0

Можете ли вы опубликовать текущую структуру данных и нужный результат? –

ответ

0

Я наконец спросил друга, который является хорошим веб-разработчик, чтобы помочь мне об этом. Он сказал мне сделать это в двумя шагами: построить объект, а затем отформатировать его так, как мне нужно.

Так что я сделал это:

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;  
}; 

Я предполагаю, что это может быть чище, но это работает, и это гораздо проще, чем я ожидал.

1

Это, безусловно, возможно с использованием нескольких циклов, но код будет довольно трудно следовать. Если вы согласны с привлечением другой библиотеки, рассмотрите 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 lib :) Спасибо, в любом случае! – enguerranws

Смежные вопросы