Meteor Tracker 不自动接收订阅

Meteor Tracker not receiving subscriptions automatically

我正在使用 Template.onCreated 创建一些模板,然后使用 Tracker.autorun 进行一些订阅,然后从服务器收集数据并将它们存储在客户端的 MiniMongo 上。

然后,我可以离开所述模板并最终将自己路由回去。但是,我注意到回来后,Blaze 没有捕获我的更改。回路由时,似乎调用了 onRendered 而不是 onCreated。这是有道理的,但是,onRendered 还没有完全响应我的所有数据更改。我注意到这是因为 minimongo 实际上没有用于 onRendered 的数据。

但是,我注意到它可以通过刷新页面来获取对象(因此调用 onCreated 并再次订阅并从服务器获取一组新数据)我的解决方法是在 onRendered 中重新订阅,但是我感觉我不应该这样做,因为我最初已经订阅了 OnCreated。这是 Meteor 的问题吗,DDP 只是变慢了吗?

假设我有一些名为 Objects 的默认通用集合。

const Objects = new Mongo.Collection("Objects"); 

所以在我的 onCreated 中我订阅了一个集合如下

Template.foo.onCreated(function () {
    var self = this;

    self.autorun(function () {
        const objId= FlowRouter.getParam("id");


            self.objectSubscription = Meteor.subscribe('obj', objId, {
                onReady: function () {

                },
                onStop: function (error) {
                    if (error) {
                        alert('error')
                    }
                }
            });

然后在 onRendered 中,我必须破解它并不必要地重新订阅,因为我没有 objId 即我不能只使用 Objects.find(),

Template.foo.onRendered(function () {
    const objId= FlowRouter.getParam("id");

    Meteor.subscribe('obj', objId, {
        onReady: function () {
            $('#obj').addClass('highlight');
        },
        onStop: function (error) {
            if (error) {
                alert('error');
            }
        }
    });

    //I feel like I should just be able to do 
    //const obj = Objects.findOne({_id:objId})
    //$('#obj').addClass('highlight')

});

任何见解,为什么我会在 minimongo 中丢失数据? "re-subscribe" 是不好的做法吗?

onCreatedonRendered 不是反应性的,但 template helpers 是。因此,要不断检测这两者的变化,您必须创建一个反应性上下文并将其放置在它们内部,这可以使用 Tracker.autorun 来实现。另外,请注意,最好保留 onRenderd 用于 DOM 操作,保留 onCreated 用于订阅和创建 reactive variables

您不需要双重订阅来检测更改,IMO 这通常是一种不好的做法。

Template.foo.onCreated(function onCreated() {
  const self = this;
  this.autorun(function() {
  const id = FlowRouter.getParam('_id');
  self.subscribe('obj', id);
  });
});


Template.foo.onRendered(function onRendered() {
  const self = this;
  // this will run after subscribe completes sending records to client
  if (self.subscriptionsReady()) {
    // do whatever you want
    $('#obj').addClass('highlight');
  }
});