2014-04-19 2 views
0

моя вложенная JSON убивает меня, кажется, я должен написать пользовательский фильтр, чтобы сделать OrderByпользовательский цикл OrderBy через вложен массив

$scope.ranking = [ 

    { 
     'uId': 2, 
      'name': 'Jeremy', 
      'tabs': [{ 
      'tabId': 1, 
       'points': 100, 
     }, { 
      'tabId': 2, 
       'points': 10 
     }], 

    }, 

    { 
     'uId': 3, 
      'name': 'Jordon', 
      'tabs': [{ 
      'tabId': 1, 
       'points': 180, 
      },{ 
      'tabId': 2, 
       'points': 5 
     }], 
    }] 


} 

, что я хочу, это рейтинг пользователей SORT точки. Было бы легко, если вкладки содержат отдельные точки, но несколько вкладок указывают типы игр, в которые они играли.

взгляд на мою скрипку, то вы будете знать, что я пытаюсь сделать, вот http://jsfiddle.net/U4dd8/

я написал свой собственный фильтр, пока здесь

app.filter("rankFilter", function(){ 
    return function (input, points) { 
     var output = [];  

      for (var i in input) { 

     for(var j in input[i].tabs){ 
     var points = input[i].tabs[j].points; 

     output.push(points); 

     } 

     } 

    return output; 
}; 
+1

Я не уверен, что правильно понял. Вы пытаетесь отображать общие баллы для каждого пользователя и сортировать пользователей в соответствии с общими точками? – kubuntu

+0

сортировать базу пользователей по пользователю –

ответ

1

Если я правильно понимаю, что вы хотите увидеть в каждая вкладка - пользователи, у которых есть баллы для этой категории, и сортировать их по точкам (для этой конкретной категории).

Это очень локализовано вопрос (а скорее не радиально-родственный), но здесь это возможное решение:

HTML:

<li ng-repeat="user in ranking | orderByPointsForTab:currentTab"> 
    <a ng-click="showFriendsTasksEvent(user.uId)"> 
     {{user.name}} {{user.tabs | pointsForTab:currentTab}} 
    </a> 
</li> 

2 используются фильтры:

  1. pointsForTab: Требуется массив tabs и currentTab в качестве аргументов и возвращает точки, связанные с текущей вкладкой.
    Это может быть функция контроллера.

  2. orderByPointsForTab: Он принимает users массив и currentTab в качестве аргументов и возвращает новый массив, содержащий только пользователи, которые имеют точки для текущей вкладки и отсортированных в порядке убывания баллов (для текущей вкладки).

Для того, чтобы понять код, приведенный ниже, вы должны быть знакомы со следующими методами Array (стандартные JS - ничего радиально-специфических):
- Array.prorotype.forEach
- Array.prorotype.some
- Array.prorotype.map
- Array.prorotype.sort

app.filter("orderByPointsForTab", function() { 

    /* `users` and `currentTab` as input */ 
    return function (users, currentTab) { 

     /* 1: Create an array of users that have points 
     * for current tab (in random order) */ 
     var unsortedUsersWithPoints = []; 
     (users || []).forEach(function (user) { 

      /* Iterate over the tabs of each user... */ 
      (user.tabs || []).some(function (tab) { 

       /* ...until we find the current tab... */ 
       if (tab.tabId === currentTab) { 

        /* ...store the user and the points for current tab 
        * for later access (see below)... */ 
        unsortedUsersWithPoints.push({ 
         user: user, 
         points: tab.points 
        }); 

        /* ...and break the loop for the current user */ 
        return true; 
       } 
      }); 
     }); 

     /* 2: Sort the array of `{user, points}` objects 
     * in descending order of points */ 
     var sortedUsersWithPoints = unsortedUsersWithPoints.sort(
      function (obj1, obj2) { 
       return obj2.points - obj1.points; 
      } 
     ); 

     /* 3: Create a new array containing only `user` objects, 
     * but keeping the order in `sortedUsersWithPoints` (see above) */ 
     var output = sortedUsersWithPoints.map(function (obj) { 
      return obj.user; 
     }); 

     /* 4. Return the sorted `users` array */ 
     return output; 
    }; 
}); 

Описанный выше код может быть найден в этом short demo.

+0

Большое вам спасибо –

0

Во-первых, поскольку у вас уже есть currentTab на вид, вы можете выбрать users для отображения для каждой вкладки, используя ng-show вместо использования дополнительных фильтров.Затем используйте специальный фильтр (orderByPoints) для реализации пользовательского сортировки, который заказывает пользователей в соответствии с вкладками.

Ваше мнение становится

<div ng-controller="AppCtrl"> 
    <button ng-click="currentTab=1">shooting</button> 
    <button ng-click="currentTab=2">dribble</button> 
    <p>Leaderboard</p> 
    <ul> 
     <li ng-repeat="user in ranking | orderByPoints: currentTab"> 
      <span ng-repeat="tab in user.tabs"> 
       <span ng-show="tab.tabId == currentTab"> 
        <a ng-click="showFriendsTasksEvent(user.uId)"> 
         {{ user.name }} - {{ tab.points }} 
        </a> 
       </span> 
      </span> 
     </li> 
    </ul> 
</div> 

Пользовательский фильтр

app.filter("orderByPoints", function() { 
    var inputTab; 
    function compare(a, b) { 
     // Check for undefined since value may be missing for some users 
     if (typeof a.tabs[inputTab] != 'undefined' && typeof b.tabs[inputTab] != 'undefined') 
      return b.tabs[inputTab].points - a.tabs[inputTab].points; 
     return 0; 
    } 
    // Filter function 
    return function (input, currentTab) { 
     inputTab = currentTab; // Get current tab 
     return input.sort(compare); // Call custom sort 
    } 
}); 

Вот обновленный Fiddle (я добавил дополнительный user и вкладку для демонстрации).

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