【发布时间】:2015-01-25 15:08:18
【问题描述】:
更新:我为我的问题提供了最佳答案。随意提高可读性和/或效率。
问题:在我的 requireJS 设置中使用 fullcalendar.io,事件对象(从对 .ashx 处理程序的 AJAX 调用接收)在每次下一个/上一个/视图更改时填充到日历上。我想在回调中使用该 JSON 对象来创建按 startDate 属性分组的事件列表。
我做了什么
在日历更新(例如新月份)上,我能够设置一个基本的 ViewModel 来使用可观察数组填充新的事件列表。唯一缺少的部分是 group by,例如 this example。由于我希望按 Event 对象的开始日期进行分组,然后按开始日期升序对每个组进行排序,因此我不确定我应该采取的最佳实践,例如是否有必要将我的 JSON 数据转换为对象。随着我了解更多,我将继续更新这篇文章。我不使用链接示例的原因是因为我不了解处理程序背后的完整术语,但目前了解一些关键字,例如 $root。
AJAX 调用和 requireJS 模块加载:fullcalendar
var fullCalendar = ".calendar-module",
viewModel;
function initFullCalendar() {
$(fullCalendar).fullCalendar({
events: {
url: '/Presentation/DotGov/test/fullcalendar/GetEvents.ashx',
type: 'POST',
success: function (data) {
// bind events to KO ViewModel object
viewModel.events(data);
}
},
});
}
// requireJS module load
return {
load: function () {
viewModel = new ViewModel();
ko.applyBindings(viewModel);
initFullCalendar();
}
};
视图模型
// Day constructor that holds the day title and an array of event objects
var Day = function() {
dayTitle = null,
events = []
}
function ViewModel() {
var self = this;
self.dates = ko.observableArray();
self.events = ko.observableArray();
self.uniqueDates = ko.computed(function () {
var allDates = ko.utils.arrayMap(self.events(), function (event) {
return new XDate(event.start).toDateString();
});
return ko.utils.arrayGetDistinctValues(allDates);
}, ViewModel);
// TODO: groupedEvents { date: /.., events: [..]}
self.groupedEvents = ko.computed(function () {
var groupedEvents = [];
var uniqueDates = self.uniqueDates();
for (var i = 0; i < uniqueDates.length; i++) {
// create new day object
var day = new Day();
day.dayTitle = uniqueDates[i];
day.events = [];
// get all events within that day
ko.utils.arrayForEach(self.events(), function (event) {
var eventDate = new XDate(event.start).toDateString();
if (eventDate == uniqueDates[i]) {
day.events[day.events.length] = event;
}
});
groupedEvents[groupedEvents.length] = day;
}
return groupedEvents;
});
}
查看
<div class="calendar-module-mobile">
<div class="day-wrapper">
<p class="day-title">Monday, April 16, 2014</p> <%--the event startDate--%>
<div class="mobile-block">
<ul data-bind="foreach: events">
<li>
<a data-bind="attr: { href: eventUrl }">
<p data-bind="text: title"></p>
<span class="icon-chevron-right turquoise-icon"></span>
</a>
</li>
</ul>
</div>
</div>
</div>
更新 我用一些计算的可观察函数更新了 ViewModel。 self.groupedEvents 遍历唯一日期列表并返回一个 Day 对象数组,其中每个 Day 对象包含唯一日期标题和一个 Event 对象数组(不是从 JSON 转换而来的)。我现在必须更新视图以查看它是否有效。
【问题讨论】:
-
阅读有关绑定上下文的文章 - knockoutjs.com/documentation/binding-context.html(关于您关于 $root 的问题)
-
我正在考虑创建一个 Day 对象列表,其中每个 Day 对象包括一个唯一的开始日期和一个与该属性匹配的 Event 对象列表。必须有一种方法来处理这些数据,而不必调用这么多开销
-
我不建议使用示例中使用的那种方法,以避免将您的演示逻辑拆分到多个不同的地方。相反,我建议在您的 ViewModel 中创建一个方法,比如说 groupEvents,它将构建结构,例如{ date: ..., events: [...] } 很容易展示。
标签: jquery ajax json mvvm knockout.js