编程语言
首页 > 编程语言> > javascript – 是否有可能在angularfire中使用.sort(compare)和.reverse数组?

javascript – 是否有可能在angularfire中使用.sort(compare)和.reverse数组?

作者:互联网

更新:我遇到的问题是做三件事的组合:

>当$priority(设置为创建日期)更改时,向数组添加标头.这样我就可以在ng-repeat中按周和日分组任务.
>在检查任务时选择该列表.检查的任务应该放在最底层.
>创建新任务时,我需要将它们添加到列表顶部而不是底部.

这是所有代码的一部分:http://plnkr.co/edit/A8lDKbNvhcSzbWVrysVm

我正在使用priorityChanged函数根据比较任务的日期添加标头:
      //控制器
      var last = null;
      $scope.priorityChanged = function(priority){
        var current = moment(priority).startOf(‘day’);
        var changed = last === null || !last.isSame(电流);
        last = current;
        回报改变了;
      };

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

并在任务完成时将任务移动到列表底部我在填充任务列表时使用.sort函数:

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-repeat将再次运行任务并添加必要的标题?这是理想的解决方案吗?标题可以分开吗?

更新:我将ng-init功能直接移动到h3中以尝试再次运行,但在这种情况下它不会显示标题.

Update2:如果$priority日期中至少有两个是唯一的,那么标题似乎确实显示但我仍然有删除或移动关联列表项删除连接标题的问题.

解决方法:

使用指令

您可以通过嵌套客户端内容来创建指令以简化操作. 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模板:

<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移出.当元素移动/度假时,我不认为这是重新运行.

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

由于您的列表可能会多次使用,因此您可能会在using track by之前获得相当大的速度提升

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

如果这不能解决问题,那么可能是时候考虑编写自己的指令(这些指令比听起来更有趣)并且可能考虑放弃AngularFire并直接进入源代码.

你真的想要一个更深层次嵌套的数据结构,你可以在多个级别进行迭代,你可能需要自己在客户端或服务器上构建它,现在你已经了解了你希望它们如何组织(基本上是一个组周功能).

标签:angularfire,javascript,firebase,angularjs
来源: https://codeday.me/bug/20190927/1825046.html