Skip to content Skip to sidebar Skip to footer

Is It Possible To .sort(compare) And .reverse An Array In Angularfire?

Update: The problem I'm having is doing a combination of three things: Adding a header to an array when the $priority (set to date created) changes. This is so I can group tasks

Solution 1:

USING A DIRECTIVE

You can create a directive to simplify things by nesting your client contents. demo

app.directive('repeatByWeek', function($parse, $window) {
  return {
    // must be an element called <repeat-by-week />
    restrict: 'E',
    // replace the element with template's contents
    replace: true,
    templateUrl: 'repeat.html',
    // create an isolate scope so we don't interfere with page
    scope: {
      // an attribute collection="nameOfScopeVariable" must exist'master': '=collection'
    },
    link: function(scope, el, attrs) {
      // get the global moment libvar moment = $window.moment;
      scope.weeks = [];
      updateList();

      // whenever the source collection changes, update our nested list
      scope.master.$watch(updateList);

      functionupdateList() {
         scope.weeks = sortItems(parseItems(scope.master));
      }

      functionsortItems(sets) {
        var items = [];
        // get a list of weeks and sort themvar weeks = sortDescending(Object.keys(sets));
         for(var i=0, wlen=weeks.length; i < wlen; i++) {
           var w = weeks[i];
           // get a list of days and sort themvar days = sortDescending(Object.keys(sets[w]));
           var weekEntry = { 
             time: w, 
             days: []
           };
           items.push(weekEntry);
           // now iterate the days and add entriesfor(var j=0, dlen=days.length; j < dlen; j++) {
             var d = days[j];
             weekEntry.days.push({
               time: d,
               // here is the list of tasks from parseItems
               items: sets[w][d]
             });
           }
         }
         console.log('sortItems', items);
         return items;
      }

      // take the array and nest it in an object by week and then dayfunctionparseItems(master) {
        var sets = {};
        angular.forEach(master, function(item) {
           var week = moment(item.$priority).startOf('week').valueOf()
           var day = moment(item.$priority).startOf('day').valueOf();
           if( !sets.hasOwnProperty(week) ) {
             sets[week] = {};
           }
           if( !sets[week].hasOwnProperty(day) ) {
             sets[week][day] = [];

           }
           sets[week][day].push(item);
         });
         console.log('parseItems', sets);
         return sets;
      }

      functionsortDescending(list) {
        returnlist.sort().reverse();
      }
    }
  }
});

The repeat.html template:

<ul><!-- 
      it would actually be more elegant to put this content directly in index.html
      so that the view can render it, rather than needing a new directive for
      each variant on this layout; transclude should take care of this but I
      left it out for simplicity (let's slay one dragon at a time)
    --><ling-repeat="week in weeks"><h3>{{week.time | date:"MMMM dd'th'" }}</h3><ul><ling-repeat="day in week.days"><h4>{{day.time | date:"MMMM dd'th'" }}</h4><ul><ling-repeat="task in day.items"><inputtype="checkbox"ng-model="task.complete"ng-change="isCompleteTask(task)"><inputng-model="task.title"ng-change="updateTask(task)"><spanng-click="deleteTask(task)">x</span></li></ul></li></ul></li></ul>

OTHER IDEAS

Most likely, you just need to move your changed out of ng-init. I don't think that is re-run when elements move/resort.

<ling-repeat="task in list"><h3ng-show="priorityChanged(task.$priority)">{{getDayName(task.$priority)}}</h3><!-- ... --></li>

Since your list may resort several times, you can probably also get a pretty significant speed boost by using track by

<li ng-repeat="task in list track by task.$id">

If that doesn't resolve the problem, it might be time to think about writing your own directive (these are more fun than they sound) and possibly to consider setting aside AngularFire and going right to the source.

You really want a more deeply nested data structure here you can iterate at multiple levels, and you may need to structure that yourself either on the client or the server, now that you have a sense of how you want them organized (essentially a group by week functionality).

Solution 2:

you could use "unshift" javascript function

var fruits = ["1", "2", "3", "4"];
fruits.unshift("5","6");

Result

[ '5', '6', '1', '2', '3', '4' ]

Post a Comment for "Is It Possible To .sort(compare) And .reverse An Array In Angularfire?"