使用Meteor JS的反应式连接在模板中渲染集合数据

时间:2015-02-23 08:12:15

标签: javascript mongodb meteor

我想使用反应联接将两个集合中的数据输出到我的模板中,然后通过公共ID将用户,帖子和评论配对。

到目前为止,我可以看到Mongo命令存在JSON数据,但我的模板没有呈现任何数据。我究竟做错了什么?

仅供参考,meteorpad没有编译,但github repo会。

回购:

https://github.com/djfrsn/frontend-interview-test-long/tree/master/ontra/ontra

Meteor Pad示例:

http://meteorpad.com/pad/SvwkNrv5grgv2uXxH/Copy%20of%20Leaderboard

2 个答案:

答案 0 :(得分:1)

您的代码不能在meteorpad上运行,因为fetchJSONData方法在common.js文件中定义之前在服务器上执行。您应该在客户端上触发事件后调用该方法,或者根本不使用方法,只需在Meteor.startup上获取JSON数据。

关于反应式连接,您似乎想要执行与文档示例1非常相似的操作:https://github.com/englue/meteor-publish-composite

答案 1 :(得分:1)

有很多错误,很难知道从哪里开始。

1)当您加载初始帖子和用户数据时,您将整个返回的数组作为一个元素插入,而不是将每个元素单独插入到您的帖子集合中。

2)您正在创建一个名为“postsSet”的发布订阅,但您尝试使用其他名称订阅它。

3)你根本没有正确地调用publishComposite。您应该发布每个帖子所需的用户作为children数组的一部分。

4)模板需要根据上述

进行更新

5)用户名需要通过帮助程序提供。

6)你应该将“id”属性映射到Mongo的“_id”。

这是有效的代码。请注意,每次重新启动时都需要调用meteor reset,否则每次重新导入数据时都会出现重复的ID错误。

Posts = new Mongo.Collection("Posts");
var groundPosts = new Ground.Collection(Posts);
Users = new Mongo.Collection("Users");
var groundUsers = new Ground.Collection(Users);

if (Meteor.isClient) {

  Meteor.subscribe("postsSet");

  console.log('POSTS DATA = ' + Posts.find().fetch());
  console.log('USERS DATA = ' + Users.find().fetch());

  Template.body.events({
    "submit .ontra": function (event) {    
    // This function is called when the new task form is submitted

    var text = event.target.text.value;

    Posts.insert({
      content: text,
      date: new Date() // current time
    });

    // Clear Form
    event.target.text.value = "";

    // Prevent default form submit
    return false
    }
  });

  Template.body.helpers({
    posts: function() {
      return Posts.find();
    },
  });

  Template.post.helpers({
    username: function() {
      return Users.findOne({_id: this.userId}).username;
    }
  });

}



Meteor.methods({
  'fetchJSONData': function() {

    var postsResponse = Meteor.http.call("GET","https://raw.githubusercontent.com/djfrsn/frontend-interview-test-long/master/codetest/data/posts.json");
    var usersResponse = Meteor.http.call("GET","https://raw.githubusercontent.com/djfrsn/frontend-interview-test-long/master/codetest/data/users.json");

    var postsData = JSON.parse(postsResponse.content);

    var usersData = JSON.parse(usersResponse.content);

    postsData.forEach(function (post) {

      post.date = new Date();
      post._id = String(post.id)
      delete post.id
      post.userId = String(post.userId)
      Posts.insert(post);
    });

    usersData.forEach(function (user) {
      user.date = new Date() // current time
      user._id = String(user.id)
      delete user.id
      Users.insert(user);
    });


  }
});




if (Meteor.isServer) {

  Meteor.publishComposite('postsSet', {
    find: function () {
      return Posts.find({});
    },
    children: [
      {
        find: function (post) {
          console.log("%j", post.userId);
          console.log("%j", Users.findOne({ _id: post.userId }));
          return Users.find({ _id: post.userId });
        }
      }
    ]
  });

  Meteor.call("fetchJSONData");
  //console.log('POSTS DATA = %j', Posts.find().fetch());
  //console.log('USERS DATA = %j', Users.find().fetch());

}

HTML:

<head>
  <title>ontra</title>
</head>

<body>

  <div class='container'>

    <header>
      <h1>ontra</h1>
            <form class='ontra'>
                <input type='text' name='text' placeholder="Type to add new post">
            </form>
    </header>
    <ul>
      {{#each posts}}
        {{> post}}
      {{/each}}
    </ul>

  </div>

</body>

<template name='post'>

  <li>
    <span class="text">{{content}}</span>
    <span class="text">{{username}}</span>
  </li> 

</template>