【问题标题】:How can I sort a firebase angularfire array into weeks and days?如何将 Firebase angularfire 数组分类为数周和数天?
【发布时间】:2014-09-17 20:39:36
【问题描述】:

我正在制作一个按周对任务进行分组的待办事项列表(基于添加日期和完成日期),并按星期几对任务进行分组。数据库结构如下所示:

users
  userA
    tasks
      taskobject1
      taskobject2
      ..
  userB
    tasks
      taskobject1
      task object2

我正在使用 ng-repeat 将所有任务显示到每个用户的视图中。我希望能够先按他们所在的星期对它们进行排序,然后像这样:

#week1
--monday--
task a
task b
--tuesday--
task c
task d
..
#week2
--monday--
task a
..

即使是概念性的答案也会有所帮助。我不知道从哪里开始。

谢谢。

【问题讨论】:

    标签: javascript angularjs firebase angularfire


    【解决方案1】:

    另请参阅这篇文章,它提供了执行此分组的指令:Is it possible to .sort(compare) and .reverse an array in angularfire?

    您可以在这里采取一些方法。

    按日期结构化的数据

    如果记录总是被这个结构获取,你可以这样存储它们;

    /users/usera/tasks/week1/monday/taska/...
    

    然后您可以简单地将它们作为对象在tasks 级别获取,您将获得一个预先排序的 JSON 对象,其值嵌套在适当的级别。

    这种方法与 AngularFire 不高度兼容,AngularFire 旨在绑定对象或集合,而不是嵌套的数据树,但应该小心使用。

    使用优先级

    第二种方法是在任务上使用add priorities,这将是一个纪元时间戳。现在,当您想要获取它们时,您可以 startAt/endAt 树中的特定点,并获取记录。每个都会有一个时间戳,您可以使用它来识别星期和日期。

    var ref = new Firebase(ref).startAt(twoWeeksAgo).endAt(nextThursday);
    $scope.list = $fireabse(ref).$asArray();
    

    但是,这不会对条目进行分段。您需要检查 ng-repeat 中的每个条目并动态添加标题:

    // in the controller
    var last = null;
    $scope.priorityChanged(priority) {
       /** 
        * here we would use a library like moment.js to parse the priority as a date
        * and then do a comparison to see if two elements are for the same day, such as 
        **/
       var current = moment(priority).startOf('day');
       var changed = last === null || !last.isSame(current);
       last = current;
       return changed;
    };
    
    $scope.getDayName = function($priority) {
       return moment($priority).format('dddd');
    };
    
    <!-- in the view -->
    <li ng-repeat="item in list" ng-init="changed = priorityChanged(item.$priority)">
       <h3 ng-show="changed">{{getDayName(item.$priority)}}</h3>
       {{item|json}}
    </li>
    

    这种方法很容易与 AngularFire 兼容。

    滚动你自己的列表

    最后一种方法是删除 AngularFire 并推出自己的方法。例如,如果我们在每个任务中存储星期和工作日,我们可以执行以下操作:

    app.service('DatedList', function($timeout) {
       return function(pathToList) {
          var list = {};
    
          pathToList.on('child_added', function(snap) {
             $timeout(function() { // force Angular to run $digest when changes occur
                var data = snap.val();
                var week_number = data.week;
                var week_day = data.day;
                list[week_number][week_day] = data;
             });
          });
    
          //todo: write similar processing for child_changed and child_removed
    
          return list;
       }
    });
    
    app.controller('ctrl', function($scope, DatedList) {
       var listRef = new Firebase(URL).limit(500);
       $scope.weeks = DatedList(listRef);
    });
    
    <div controller="ctrl">
      <div ng-repeat="(week, days) in weeks">    
         <h1>{{week}}</h1>
         <div ng-repeat="(day, items) in days">
            <h2>{{day}}</h2>
            <div ng-repeat="item in items">
               {{item|json}}
            </div>
         </div>
      </div>
    </div>
    

    【讨论】:

    • 我正准备尝试“自己动手”的方法,但我很早就遇到了问题。我收到一条错误消息:TypeError:无法设置未定义的属性“1”。我正在研究 plunkr,所以我可以更好地解释这个问题,但我完全按照你指定的方式:plnkr.co/edit/M4zEjpZ4kqTKn1sHHMt6 我还没有走得太远,我尝试了一周和一天的值 52 和 1。谢谢@加藤
    • 您没有在作用域中定义task,因此您的ng-submit="addTask()"ng-model="task.text" 指令都引用了一个不存在的对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    相关资源
    最近更新 更多