【问题标题】:Single view page permalink empty with Iron RouterIron Router 的单一视图页面永久链接为空
【发布时间】:2015-01-28 18:21:13
【问题描述】:

我在 Iron-Router 中设置了两条路由:“home”(所有帖子的分页列表)和“doc”(详细视图)。主页加载得很好,但只有在以前查看过主页时才能加载详细视图。否则它将呈现为空 - 并且不能用作永久链接。

这将始终加载: http://localhost:3000/

只有在之前查看过“home”时才会加载: http://localhost:3000/doc/tZFawq8cgf43hZBaJ

路线:

Router.map(function() {
    this.route('home', {
        path: '/'
    });
    this.route('doc', {
        path: '/doc/:_id',
        data: function() {
            return MyPix.findOne({_id: this.params._id});
        }
    });
});

文档模板:

<template name="doc">
    <h1>{{this.name}}</h1>
    <img src="{{ this.url store='OriginalRetinaPix' }}" width="{{ this.metadata.width }}" height="{{ this.metadata.height }}" />
</template>

发布/订阅:

Meteor.publish('MyPix', function(cursor) {
    Counts.publish(this, 'numberOfPosts', MyPix.find(), { noReady: true });
    return MyPix.find({}, {sort: {uploadedAt: -1}, limit: 4, skip: cursor});
});

if(Meteor.isClient) {
    Session.setDefault('docCursor', 0);
    console.log('docCursor: ' + Session.get('docCursor'));
    Meteor.autorun(function(){
        Meteor.subscribe('MyPix', Session.get('docCursor'));
    })
}

顺便说一句:GitHub上的项目

【问题讨论】:

    标签: javascript meteor iron-router


    【解决方案1】:

    在您的“doc”路由上,您应该使用waitOn 以便在页面加载时准备好数据。在Router.configure中也添加加载模板

    我建议您升级到新的 iron:router 路由声明并添加 meteorhacks:subs-manager 以便更好地缓存订阅。

    这是一个应该适用于您的情况的示例

    var subs = new SubsManager();
    Router.route('/doc/:_id', {
      name: 'doc',
      template: 'doc',
      waitOn: function() {
        return subs.subscribe('aPix', this.params._id);
      },
      data: function() {
        return {
          apix: MyPix.findOne({
            _id: this.params._id
          })
        };
      }
    });
    

    并在服务器端创建一个publications.js

    Meteor.publish('aPix', function(id) {
      check(id, String);
      return MyPix.find(id);
    });
    

    【讨论】:

    • 谢谢@radu-chiriac! - 这对我有用 - 有一个小的编辑。必须将数据更改为data: function() { return MyPix.findOne({_id: this.params._id}); } 在发布功能中我不明白的一件事是为什么它与MyPix.find(id) 一起使用——而不是MyPix.find(_id)
    • 在上面的评论中找到了我最后一个问题的答案(关于 id 名称):它只是参数的名称。我有点尴尬... ;) 再次感谢!
    • true,如果您暂时不想将其作为模板变量。当每个路由有更多订阅时,请确保将它们作为对象返回,就像我对“apix”所做的那样。至于publications.js,“id”作为函数参数传递。
    【解决方案2】:

    使用这个。

    Router.map(function() {
        this.route('home', {
            path: '/'
        });
        this.route('doc', {
            path: '/doc/:_id',
            waitOn: function(){ 
                 return Meteor.subscribe('MyPix');
            },
            data: function() {
                return MyPix.findOne({_id: this.params._id});
            }
        });
    });
    

    您的订阅也应该是这样的。

    Meteor.publish('MyPix', function(cursor) {
        //Counts.publish(this, 'numberOfPosts', MyPix.find(), { noReady: true });
        return MyPix.find({});
    });
    

    另外加meteor add sacha:spin,因为人多的时候订阅会有一点延迟。

    将此添加到每条路线。

    loadingTemplate: "loading"
    
    <template name="loading">
        {{> spinner}}
    </template>
    
    Router.onBeforeAction("loading");
    

    万一您在 'home' 上显示 100 多张图片并且有人进入并且连接速度很慢,他会认为页面加载为空,或其他什么。

    【讨论】:

    • 感谢@Ethaan! waitOn 功能解决了基本问题!但我采用了仅为 id 创建单独订阅的方法(如上所述)。这使我当前在“主页”上的分页保持不变——并且发布的数据集更小(如果我理解正确的话)。
    【解决方案3】:

    您只订阅了所有文档的一个子集。如果您直接转到/doc/tZFawq8cgf43hZBaJ,则 ID 为tZFawq8cgf43hZBaJ 的文档可能不在您在客户端收到的文档子集中。

    注意:如果这个答案是正确的,你应该可以直接去/doc/&lt;id&gt;查看那些首先出现在主页上的文档(在第一页,当会话变量docCursor是0时) .

    【讨论】:

    • 是的,我也是这么想的。但是即使我在第一页上取了四个 _id 中的一个,我也遇到了问题。 waitOn 函数似乎是以下答案中建议的解决方案。谢谢! :)
    • @Kai,我认为waitOn 也可能是问题所在,但这没有意义。您的路由中的 data 函数是反应式的,因此当客户端从服务器接收到影响其中光标的新信息时会重新计算它,这应该会导致文档在一段时间后正确呈现(当订阅准备好时) .奇怪。
    猜你喜欢
    • 2015-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 2016-11-10
    相关资源
    最近更新 更多