Meteor 更新 JQuery 插件数据

Meteor update JQuery plugin data

我有一个使用 Blaze 模板的 Meteor 应用程序,旨在为日记提供动力,显示部分由 JQuery FullCalendar 处理。我正在向 fullcalendar 传递一个回调以用于显示事件,效果很好。不过,我无法让它以反应方式运行——日记将同时在多个设备上使用,我希望事件立即在所有设备上更新。我能够更新集合,我可以看到更改被推送到 minimongo 订阅,但是我无法更新日历。有没有我可以挂钩的事件,我可以在其中强制日历重新获取事件?看起来这应该是一个相当常见的用例?

当前代码如下:

Diary.js:

Template.Diary.onCreated(function() {
    this.autorun(() => {
        this.subscribe('bookings');
    });
});

Template.Diary.helpers({
    dataReady : function() {
      return Template.instance().subscriptionsReady();
    },
    events: function () {
        const instance = Template.instance();
        var fc = $('.fc');
        return function (start, end, tz, callback) {
                //console.log(instance.data.bookings);
                //find all, because we've already subscribed to a specific range
                var events = Bookings.find().map(function (bk) {
                    return {
                        title: bk.serviceName,
                        start: bk.bookingDate,
                        editable: bk.bookingDate > new Date(),
                        allDay: false
                    };
                });
                console.log(events);
                callback(events);
        };
    },
    onEventClicked: function() {
        return function(calEvent, jsEvent, view) {
            alert("Event clicked: "+calEvent.title);
        }
    }
});

Template.Diary.rendered = function () {
    const instance = Template.instance();
    var fc = this.$('.fc');

    this.autorun(function () {
        console.log("refetching events");
        fc.fullCalendar('refetchEvents');
    });
};

代码 console.log("refetching events"); 只被调用一次,每当预订订阅发生变化时,我都需要调用此代码。

Diary.html(已删除附加标记):

{{#if dataReady}}
    {{> fullcalendar
            class="fc"
            defaultView='agendaWeek'
            height="100%"
            events=events
            eventClick=onEventClicked
    }}
{{else}}
    <div class="calendar_loading">Loading...</div>
{{/if}}

实际的 FullCalendar 显示在它自己的组件中,该组件基于打包在 Atmosphere 上的组件 - 我可能会对其进行大量定制,并且还希望控制插件版本,因此不直接使用。该组件如下:

fullcalendar.js:

Template.fullcalendar.rendered = function() {
    var div = this.$(this.firstNode);
    if(this.data != null) {
        div.attr('id', this.data.id);
        div.addClass(this.data.class);
    }
    div.fullCalendar(this.data);
};

fullcalendar.html

<template name="fullcalendar">
    <div class="fc"></div>
</template>

我认为更改您的 onRendered 方法应该可以解决问题。

Template.Diary.onRendered = function () {
  var self = this;

  this.autorun(function () {
      Bookings.find().fetch();
      var fc = self.$('.fc');
      fc.fullCalendar('refetchEvents');
  });
};

您的 autorun 中必须有一个响应式数据源,以确保它在数据更改时执行。在这种情况下,我们实际上不需要在 autorun 中获取数据,因为您使用的是 FullCalendar 事件回调。所以 Bookings.find().fetch() 只是确保每次集合更改时 refetchEvents 是 运行.

查看此 tutorial 以备不时之需。