【问题标题】:Meteor onRendered function and access to CollectionsMeteor onRendered 函数和对 Collections 的访问
【发布时间】:2015-07-21 02:24:42
【问题描述】:

当用户刷新某个页面时,我想从 mongoDB 数据库中设置一些初始值。

我尝试使用 onRendered 方法,在文档状态中,当它运行的模板插入 DOM 时,该方法将运行。但是,该数据库在该实例中不可用?

当我尝试从函数访问数据库时:

Template.scienceMC.onRendered(function() {
    var currentRad = radiationCollection.find().fetch()[0].rad;
}

我收到以下错误消息:

Exception from Tracker afterFlush function:
TypeError: Cannot read property 'rad' of undefined

但是,当我在控制台中运行 radiationCollection.find().fetch()[0].rad; 行时,我可以访问该值吗?

如何确保 mongoDB 的副本可用?

【问题讨论】:

  • 你在用 Iron-router 吗?
  • @Billybobbonnet 是的,我添加了路由器包并使用它来将 http 定向到模板。
  • @ArashSaidi 您需要waitOn 您的数据或保护它。我在this post 中详细解释了这些技术。
  • @David Weldon,如果他打算保护他的数据,是否应该将他的查询包装在跟踪器 autorun 函数中?因为守卫会避免渲染的错误,但是一旦数据可用,它会重新运行吗?
  • 是的,这个很难直接回答,因为数据是在onRendered 中读取的,我不知道它是如何使用的。可能autorun 是正确的答案,但是在不了解用例的情况下将他引向那个方向可能会有一些缺陷。 waitOn 是一个简单的答案,但它依赖于 IR,可能是也可能不是正确的用户体验。

标签: mongodb meteor collections


【解决方案1】:

对我来说最好的方法是使用路由器中的 waitOn 功能。感谢@David Weldon 的提示。

Router.route('/templateName', {
    waitOn: function () {
        return Meteor.subscribe('collectionName');
    },
    action: function () {
        // render all templates and regions for this route
        this.render();
    }
});

【讨论】:

    【解决方案2】:

    您需要设置一个正确的发布(您似乎已经做到了)并订阅路由参数。如果您想确保在onRendered 函数中有效地拥有您的数据,您需要添加一个额外的步骤。

    这是一个如何在您的路线定义中制作它的示例:

    this.templateController = RouteController.extend({
        template: "YourTemplate",
    
        action: function() {
            if(this.isReady()) { this.render(); } else { this.render("yourTemplate"); this.render("loading");}
            /*ACTION_FUNCTION*/
        },
    
        isReady: function() {
    
    
            var subs = [
                Meteor.subscribe("yoursubscription1"),
                Meteor.subscribe("yoursubscription2")
            ];
            var ready = true;
            _.each(subs, function(sub) {
                if(!sub.ready())
                    ready = false;
            });
            return ready;
        },   
        data: function() {
            return {
                params: this.params || {}, //if you have params
                yourData: radiationCollection.find()
            };
        }
    });
    

    在本例中,您在onRendered 函数中获得了使用this.data.yourDataradiationCollection.find() 的数据

    编辑:正如@David Weldon 在评论中所说,您还可以使用更简单的替代方法:waitOn

    【讨论】:

    • 这似乎是为了访问我已经订阅的数据?我希望有更优雅的方式来做到这一点?
    • 我不确定你的意思。除了您的出版物之外,在您的路线选项中,只有当您的订阅已启动并准备好时,您才能加载模板。这样,您可以在呈现模板时获取数据。为什么你认为它不优雅?
    【解决方案3】:

    我看不到您的收藏,所以我不能保证 rad 是您收藏中的一个键,也就是说我相信您的问题是您的收藏尚不可用。正如@David Weldon 所说,您需要保护或等待您的订阅可用(记住它必须加载)。

    我在 Ironrouter 中所做的是:

    data:function(){
        var currentRad = radiationCollection.find().fetch()[0].rad;
        if (typeof currentRad != 'undefined') {
            // if typeof currentRad is not undefined
            return currentRad;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      • 2016-03-25
      • 2015-06-22
      • 2017-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多