更新:我遇到的问题是做三件事:
以下是所有代码的一部分: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日期是唯一的,那么标题似乎会显示,但我仍然有删除或移动关联列表项删除连接标题的问题。
答案 0 :(得分:2)
使用指令
您可以通过嵌套客户端内容来创建指令以简化操作。 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并直接进入源代码。
你真的想要一个更深层嵌套的数据结构,你可以在多个级别进行迭代,你可能需要在客户端或服务器上自己构建,现在你已经了解了你希望它们如何组织(基本上按周分组功能)。
答案 1 :(得分:0)
您可以使用“unshift”javascript功能
var fruits = ["1", "2", "3", "4"];
fruits.unshift("5","6");
结果
[ '5', '6', '1', '2', '3', '4' ]