【问题标题】:Meteor Client-side Collection Document Appears and DisappearsMeteor 客户端采集文档出现和消失
【发布时间】:2016-09-06 06:41:41
【问题描述】:

经过大量阅读,我开始更好地处理 Meteor 的发布/订阅模型。我已经从我的第一个应用程序中删除了自动发布训练轮,虽然我几乎可以正常工作,但我发现了一个问题。

当应用首次加载时,我的发布和订阅钩子运行良好。我有一个在Tracker.autorun() 块中运行的代码块,它进行订阅调用,我可以在订阅句柄上使用ready() 顺序等待来自服务器的数据,等等。

我的应用程序的一个特点是它允许用户将新文档插入到集合中。更具体地说,当用户执行某个操作时,这会触发插入。此时,客户端 JS 运行,并且插入 MiniMongo 完成。反应式autorun 块运行,客户端可以看到插入的文档。客户端使用新插入的数据更新 DOM,一切正常。

此外,当我查看服务器端 MongoDB 时,我看到了插入的文档,这意味着服务器端 JS 也运行良好。

这就是奇怪的地方。客户端 autorun 块第二次运行(我不知道为什么),这一次,客户端不再有插入的项目。当 DOM 呈现时,新插入的项目现在消失了。如果我重新加载页面,一切都会恢复正常。

以前有人见过这种行为吗?我还注意到服务器端发布调用在页面加载时运行一次,但在插入后它不会再次运行。这似乎是错误的,因为客户端在插入之后(即在 Meteor 的客户端延迟补偿之后)如何从服务器获取协调后的数据?

重要的功能(ComponentInstances 是被窃听的集合):

发布块:

Meteor.publish('allComponentInstances', function (documentId, screenIndex) {
    console.log(`documentId: ${documentId} screenIndex: ${screenIndex}`)
    const screens = Screens.find({ownerDocumentId: documentId})
    const selectedScreen = screens.fetch()[screenIndex]
    return ComponentInstances.find({_id: {$in: selectedScreen.allComponentInstanceIds}})
})

autorun中的订阅块:

// ... a bunch of irrelevant code above
const allComponentInstancesHandle = Meteor.subscribe('allComponentInstances', document._id, 0)
if (allComponentInstancesHandle.ready()) {
  isReady = true
  screens = Screens.find({ownerDocumentId: document._id}).fetch()
  const componentInstanceObjects = ComponentInstances.find().fetch()
  allComponentInstances = {}
  componentInstanceObjects.map((componentInstance) => {
    allComponentInstances[componentInstance._id] = componentInstance
  })
}

【问题讨论】:

    标签: meteor reactjs


    【解决方案1】:

    我最终以不同的方式解决了这个问题。我相信,核心问题与接受/拒绝规则无关。事实上,他们的角色对我来说仍然是朦胧的。

    我现在意识到我在 Meteor 文档中一直在阅读的内容:发布函数返回游标。如果游标本身没有改变(例如,如果您正在传递要获取的特定键),那么它不会真正作为反应数据源工作,因为集合中的新文档不会使数据发布再次。毕竟,您仍在请求相同的密钥。

    前进的道路是想出一个准确反映您想要检索的反应数据的发布游标。这听起来很抽象,但在实践中,这意味着确保光标是通用的,而不是特定于您正在检索的特定键。

    【讨论】:

      【解决方案2】:

      这很可能是您从客户端插入文档。而且您没有正确设置权限规则。当您从应用程序中删除 autopublishinsecure 时,除非您在服务器端设置了 allow/deny 规则,否则不允许将文档插入/更新/删除到集合中。

      Meteor 有一个很棒的功能叫做latency compensation,它会在它获得数据库中的实际写入操作之前尝试模拟您的数据库操作。当服务器尝试写入数据库时​​,它会查找allow/deny 规则。如果权限规则不允许数据库操作或无论出于何种原因(允许/拒绝或身份验证)实际上并未写入数据库,然后服务器数据与您的客户端数据库同步。

      这就是为什么我假设您是第一次看到您的文档被插入并在一秒钟内消失。

      查看流星文档的这一部分。 http://docs.meteor.com/#/full/allow

      【讨论】:

      • 听起来可能是这样。因此,我在我的应用程序的密钥集合上添加了一些规则。然而,一切都没有改变。我还在这些方法中放置了一些控制台日志记录调用,看起来允许规则没有被调用。最后,我更进一步,阅读了不安全的包。这样做后,问题仍然存在。还有其他想法吗?
      • 如果您的代码在 github 上,请随时分享。否则在 github 中制作更小的应用程序版本来重现问题。
      猜你喜欢
      • 2013-05-27
      • 2016-06-25
      • 1970-01-01
      • 1970-01-01
      • 2014-01-16
      • 1970-01-01
      • 2014-01-09
      • 2016-04-15
      • 1970-01-01
      相关资源
      最近更新 更多