是否有可能的.sort(比较),并在.reverse的angularfire阵列? [英] Is it possible to .sort(compare) and .reverse an array in angularfire?

查看:94
本文介绍了是否有可能的.sort(比较),并在.reverse的angularfire阵列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:我有做的三件事情的组合问题:

Update: The problem I'm having is doing a combination of three things:


  1. 添加页眉到一个数组时,$优先级(设置为创建日期)的变化。这是这样我就可以按周和天团的任务在NG-重复。

  2. 诉诸该列表当任务被选中。检查任务应该去底部。

  3. 当创建新的任务,我需要将它们添加到列表中,而不是底部的顶部。

下面是所有code的plnkr: http://plnkr.co/edit/A8lDKbNvhcSzbWVrysVm

Here is a plnkr of all the code: http://plnkr.co/edit/A8lDKbNvhcSzbWVrysVm

我使用的是priorityChanged功能基础上添加比较上的任务日期的标题:
      //控制器
      VAR最后= NULL;
      $ scope.priorityChanged =功能(优先级){
        VAR电流=时刻(优先级)了.startof('天');
        VAR改变=最后===空|| !last.isSame(电流);
        最后=电流;
        返回更改;
      };

I'm using a priorityChanged function to add a header based on comparing the dates on a task: //controller var last = null; $scope.priorityChanged = function(priority) { var current = moment(priority).startOf('day'); var changed = last === null || !last.isSame(current); last = current; return changed; };

//view
<li ng-repeat="task in list track by task.$id">
  <h3 ng-show="priorityChanged(task.$priority)">{{getDayName(task.$priority)}}</h3>

和当任务完成后我使用的.sort功能,当我填充任务列表任务移动到列表的底部:

and to move a task to the bottom of the list when a task is completed I am using a .sort function when I populate the task list:

var populateTasks = function(start, end) {
    $scope.start = start;
    $scope.end = end;
    var ref = new Firebase('https://plnkr.firebaseio.com/tasks').startAt(start).endAt(end);
    var list = $firebase(ref).$asArray();

    list.sort(compare);

    list.$watch(function() {
      list.sort(compare);
    });

    function compare(a, b) {
      return a.completeTime - b.completeTime;
    }

    $scope.list = list;

  };

这好像这些方法不会一起工作。是否有它们组合从而在列表时重新排序的NG-重复将通过任务再次运行,并添加必要的标头的方法吗?是理想的解决方案?标题可以是分开的?

It seems as though these approaches will not work together. Is there a way of combining them so that when the list is re-sorted the ng-repeat will run through the tasks again and add the necessary headers? Is that the ideal solution? Can the header be separate?

更新:我直接移动的NG-初始化功能集成到H3,试图得到再次运行,但它不会显示在这种情况下头。

Update: I moved the ng-init functionality directly into the h3 to try to get that to run again but it does not display the header in that case.

UPDATE2:头似乎确实显示,如果在至少两个$优先权日期的是独一无二的,但我仍然有删除或移动相关联的列表项除去连接头的问题。

Update2: The header does seem to show up if at least two of the $priority dates are unique but I still have the problem of deleting or moving the associated list item removing the connected header.

推荐答案

使用指令

您可以创建一个指令通过嵌套客户端的内容,以简化的东西。 <大骨节病>演示

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 lib
      var moment = $window.moment;
      scope.weeks = [];
      updateList();

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

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

      function sortItems(sets) {
        var items = [];
        // get a list of weeks and sort them
        var 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 them
           var days = sortDescending(Object.keys(sets[w]));
           var weekEntry = { 
             time: w, 
             days: []
           };
           items.push(weekEntry);
           // now iterate the days and add entries
           for(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 day
      function parseItems(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;
      }

      function sortDescending(list) {
        return list.sort().reverse();
      }
    }
  }
});

该repeat.html模板:

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)
    -->
    <li ng-repeat="week in weeks">
    <h3>{{week.time | date:"MMMM dd'th'" }}</h3>
    <ul>
      <li ng-repeat="day in week.days">
        <h4>{{day.time | date:"MMMM dd'th'" }}</h4>
        <ul>
          <li ng-repeat="task in day.items">
            <input type="checkbox" ng-model="task.complete" ng-change="isCompleteTask(task)">
            <input ng-model="task.title" ng-change="updateTask(task)">
            <span ng-click="deleteTask(task)">x</span>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

其他的想法

最有可能的,你只需要移动你变出NG-的init。我不认为这是重新运行时移动的元素/度假区。

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.

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

由于您的列表可能诉诸几次,你可能还可以获得通过的使用轨道由

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

如果不解决这个问题,它可能是时间来考虑如何编写自己的指令(这些都是比他们​​听起来更有趣),​​并可能考虑预留AngularFire和去权利的来源。

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).

这篇关于是否有可能的.sort(比较),并在.reverse的angularfire阵列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆