【问题标题】:Meteor - Problems caused by Meteor.user() not defined at initial page load. How can I wait until Meteor.user() is available/defined?Meteor - 由 Meteor.user() 引起的问题在初始页面加载时未定义。我怎样才能等到 Meteor.user() 可用/定义?
【发布时间】:2019-03-19 23:21:12
【问题描述】:

在我的 Meteor 应用程序中,我有一些我想在登录后立即订阅的收藏,以及我想在用户访问或重新访问初始主页时订阅的其他收藏,但不是其他的。

第一组集合应始终订阅,但第二组集合应在用户离开并返回初始屏幕时关闭和打开。

我有以下代码:

Meteor.startup(function () {
    Meteor.subscribe('collection_one', Meteor.user().profile.setting_one);
    Meteor.subscribe('collection_two', Meteor.user().profile.setting_two);
});

Router.route('/', {
    name: 'home',
    path: '/',
    template: 'home',
    waitOn: function() {
        return [
            Meteor.subscribe('collection_three', Meteor.user().profile.setting_three),
            Meteor.subscribe('collection_four', Meteor.user().profile.setting_four),
        ]
    }
});

我的问题是,在启动后立即进入主页,Meteor.user() 返回未定义。我想等到 Meteor.user() 被定义,然后再采取这些行动。我该怎么做?

【问题讨论】:

    标签: meteor


    【解决方案1】:

    Meteor.startup() 不会将代码作为响应式计算运行,因此即使 Meteor.user() 是响应式数据源,它也不会触发计算。

    reactivity section of the docs 有一个函数列表,这些函数将代码作为响应式计算运行。

    您可以使用 Tracker(以前称为“Deps”)创建反应式计算,如下所示:

    Tracker.autorun(function () {
      if (Meteor.user()) {
        Meteor.subscribe('collection_one', Meteor.user().profile.setting_one);
        Meteor.subscribe('collection_two', Meteor.user().profile.setting_two);
      }
    });
    

    但看起来您正在使用 Iron Router,因此您还可以使用 Router.configure 设置全局 waitOn() 来解决它,如下所示:

    Router.configure({
      layoutTemplate: 'MasterLayout',
      loadingTemplate: 'Loading',
      notFoundTemplate: 'NotFound',
      templateNameConverter: 'upperCamelCase',
      routeControllerNameConverter: 'upperCamelCase',
    
      // This method will re-run when ever Meteor.user() changes.
      waitOn: function () {
    
        // Making sure setting_one and setting_two are available (which they won't be initially)
        var setting_one = Meteor.user() && Meteor.user().profile && Meteor.user().profile.setting_one;
        var setting_two = Meteor.user() && Meteor.user().profile && Meteor.user().profile.setting_one;
    
        // Subscribe to the published version of the server side collections
        return [
          Meteor.subscribe('collection_one', setting_one),
          Meteor.subscribe('collection_two', setting_two)
        ];
      }
    });
    

    【讨论】:

    • Tracker.autorun 解决方案可能是更正确的逻辑。 waitOn 解决方案不会没有反应吗? (尽管它会解决他的Meteor.user()没有被填充的初始化问题)
    • @colllin - Iron Router 的 waitOn() 实际上是反应式的,所以它可以工作。
    【解决方案2】:

    关键是使用Tracker.autorun()

    import { Meteor } from 'meteor/meteor';
    import { Tracker } from 'meteor/tracker';
    
    let username = ''
    Tracker.autorun( function(currentComputation) {
        if (Meteor.user()) {
            username = Meteor.user().username
            if (username) // do something with username
            return
        }
    })
    

    currentComputation 是可选的

    【讨论】:

      猜你喜欢
      • 2017-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-08
      • 1970-01-01
      • 2018-02-23
      • 1970-01-01
      相关资源
      最近更新 更多