如何在从集合创建数组时保持数据“响应式”

3
我正在将fullCalendar集成到我的Meteor应用程序中。fullCalendar需要特定的data format。我可以从我的Collection创建该数据。但是,该数据不再具有反应性。
有什么方法可以使我从我的Collection转换的数据变得“反应性”?
谢谢。
客户端HTML:
<template name="carpool_calendar">
  <div id="calendar"></div>
</template>

客户端JS:
Template.carpool_calendar.rendered = function () {  
  //initialize the calendar in this template
  $('#calendar').fullCalendar({    
    events: function(start, end, callback) {
      var events = [];      
      var calendarEvents = Carpool_Events.find();

      calendarEvents.forEach(function (carpool_event) {
    events.push({
          title: carpool_event.owner,
          start: carpool_event.eventDate
    });
    console.log("Event owner " + ": " + carpool_event.owner);
      });
      callback(events);
    },
    header: {
      left: 'prev,next today',
      center: 'title',
      right: 'month,basicWeek,basicDay'
    }, 
    weekends: false, // will hide Saturdays and Sundays
    editable: true
  });
};

更新客户端JS(目前还不太对。它在每次数据更改时重新创建日历...页面会随着新的日历实例变得越来越长):

Template.carpool_calendar.rendered = function () {  
  Meteor.autorun(function() {
    //initialize the calendar in this template
    $('#calendar').fullCalendar({    
      events: function(start, end, callback) {
    var events = [];      
    var calendarEvents = Carpool_Events.find();

    calendarEvents.forEach(function (carpool_event) {
      events.push({
            title: carpool_event.owner,
            start: carpool_event.eventDate
      });
      console.log("Event owner " + ": " + carpool_event.owner);
    });
    callback(events);
      },
      header: {
    left: 'prev,next today',
    center: 'title',
    right: 'month,basicWeek,basicDay'
      }, 
      weekends: false, // will hide Saturdays and Sundays
      editable: true
    });
  })};

客户端JS完全工作的“响应式”fullcalendar:
Template.carpool_calendar.rendered = function () {  
  //initialize the calendar in this template
  $('#calendar').fullCalendar({    
    events: function(start, end, callback) {
      var events = [];      
      var calendarEvents = Carpool_Events.find();

      calendarEvents.forEach(function (carpool_event) {
    events.push({
          title: carpool_event.owner,
          start: carpool_event.eventDate
    });
    console.log("Event owner " + ": " + carpool_event.owner);
      });
      callback(events);
    },
    header: {
      left: 'prev,next today',
      center: 'title',
      right: 'month,basicWeek,basicDay'
    }, 
    weekends: false, // will hide Saturdays and Sundays
    editable: true
  });

  Meteor.autorun(function() {
    var calendarEvents = Carpool_Events.find();
    $('#calendar').fullCalendar('refetchEvents');
  });

};
2个回答

5

就像 TimDog 所说的那样,你不能给 UI 元素一个响应式数组,让它自己处理其余部分。但另一个选择是你可以使用 Meteor.autorun,这样当你的集合发生变化时,它可以触发一个 JS 函数来创建一个更新后的数组,从而使其具有某种程度的响应性。

我不确定如何精确地使用这个日历,但将其添加到客户端代码中可能会有所帮助。

Meteor.autorun(function() {
    calendarEvents = Carpool_Events.find();

    $('#calendar').fullCalendar({    
        events: function(start, end, callback) {
            var events = [];      

            calendarEvents.forEach(function (carpool_event) {
                events.push({
                title: carpool_event.owner,
                start: carpool_event.eventDate
            });
       });
      callback(events);
    }
  });
});

谢谢。我会尝试这个并回报。 - shinank
没有,我什么都没改。我会更新我的帖子并附上更新后的代码,这样你就可以看到了。 - shinank
@shinank 我尝试了你的更新帖子,但是如果我向日历添加新内容,仍然会出现多个日历渲染。当您添加新项目时,是否曾遇到过此问题? - Chris
@Chris,我没有看到日历的多个“observable”渲染。你是如何检查多个渲染的?我会做同样的事情并让你知道。 - shinank
@shinank 我通过将其放入与父模板不同的模板中解决了这个问题,我使用了 Template.calContainer.rendered = function () { ... 而不是 autorun。 - Chris
显示剩余5条评论

2
这是一个更大的问题的一部分,涉及如何适当地为Meteor创建UI组件以确保反应式数据上下文。这是一个非常好的问题,以前曾经问过
简短的答案是还没有标准化的框架,比如Meteor.UI智能包。然而,在此期间,您最好使用{{#each}}助手源代码来修改fullCalendar小部件作为指南。您需要注意数据元素如何使用Spark进行标记:
 'each': function (data, options) {
    var parentData = this;
    if (data && data.length > 0)
      return _.map(data, function(x, i) {
        // infer a branch key from the data
        var branch = (x._id || (typeof x === 'string' ? x : null) ||
                      Spark.UNIQUE_LABEL);
        return Spark.labelBranch(branch, function() {
          return options.fn(x);
        });
      }).join('');
    else
      return Spark.labelBranch(
        'else',
        function () {
          return options.inverse(parentData);
        });
  },

我没有选择这个选项的唯一原因是因为我不想改变fullcalendar。 - shinank
很高兴你解决了它...我认为你眼下做出了明智的选择! - TimDog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接