1

我有一个想用 Meteor 构建的 Newsfeed 想法,但是我在弄清楚如何使 News Feed 本身保持不变时遇到了一些困难,这不是反应性的,而是更新子项目(评论,喜欢等)一旦更新。

我将所有内容都存储在一个集合中,如果可能的话,我想保持这种状态。所以集合是这样设置的:

[
    {
        title: 'A random title',
        date_created: '01/01/2001',
        comments:
            [
                {'message': 'Lorem ipsum', date_created: '01/01/2001'},
                [...]
            ]
    },
    [...]
]

所以我想做的是让新闻源不反应,这样当插入或更新新的新闻项目时,保存新闻列表的模板不会被重新呈现。但是,如果添加、删除评论或有人喜欢新闻提要,我希望立即在模板中更新。

我一直试图弄清楚如何使用{{#isolate}}{{#constant}}但没有占上风。

这是我的客户端JS:

Template.group_feed.feed_data = function() {
    var feed = Newsfeed.find({}, {
        sort: {updated_time: -1},
        limit: 10,
        reactive: false
    }).fetch();

    return feed;
};

我设置reactive: false它不更新模板,但是在更新评论或喜欢时也使它成为静态。所以我猜有更好的方法来做到这一点,然后让整个集合不反应。

这是我的模板代码:

<template name="group_feed">
    <div id="feed-wrapper">
        <ul>
            {{#each feed_data}}
                {{> group_feed_item}}
            {{/each}}
        </ul>
    </div>
</template>

<template name="group_feed_item">
    <li>
        <h1>{{title}}</h1>
        <div class="comments">
            {{#each comments}}
                <p>{{message}}</p>
            {{/each}}
        </div>
    </li>
</template>

任何人都有实现这一目标的好方法?

4

5 回答 5

1

您在这里有两个选择。(我将使用咖啡脚本作为我的伪代码)

  • 使用观察变化

    NewsCursor = NewsItems.find()
    NewsCursor.observeChanges
      changed: (id, fields) ->
        if fields.comments
          Session.set ("commentsForId"+id), fields.comments
    
  • 将您的数据分成两个集合:一个用于帖子,另一个用于评论。

如果你不做其中之一,{{isolate}} 不会帮助你。使用您当前的数据设置,Meteor 只会查看帖子是否更改,并在更改时更新任何模板;它不会跟踪哪个部分发生了变化。

于 2013-04-25T12:37:06.977 回答
0

我没有测试它,但我想限制客户端的订阅是最直接的,从而减少数据传输并消除对保留的需要:

它会是这样的:

在服务器上:

Meteor.publish('tenItemsBefore',function (time) {
  Newsfeed.find({updated_time: {$lt time}}, {
  sort: {updated_time: -1},
  limit: 10
})}

在客户端,在反应上下文中,例如。在 Meteor.autorun() 中:

Newsfeed.subscribe('tenItemsBefore',Session.get('lastUpdate'));

在客户端,由事件触发,例如。使用路由器包刷新:

Session.set('lastUpdate', (new Date()).getTime());

希望有帮助,

最好的,简

于 2013-03-10T20:42:47.797 回答
0

我很确定问题在于您返回的是数组而不是游标。似乎 Spark 对两者的行为有所不同。

.fetch()从提要查询的末尾删除。

有关这些东西如何工作的更多信息,我强烈建议在http://www.eventedmind.com/上查看 Chris Mather 的精彩演讲

具体来说,慢动作反应性说明了数组和光标之间的区别: http ://www.eventedmind.com/posts/meteor-ui-reactivity-in-slow-motion

更新:在我原来的答案中,我没有完全理解问题 - 我很抱歉,所以关于删除 fetch() 的内容对你没有帮助。以下是您可能想要探索的几个选项:

  1. 使用 Meteor.observe 或Meteor.observeChanges来观察评论字段的变化,并使用代码(“手动”)更新 DOM。

  2. 在服务器端创建一个自定义集合,仅发布原始集合中的评论。所以我不建议你改变存储在 mongo 中的数据模型,只是发布一个不同的视图。通过这种方式,可能更容易继续使用模板来更新评论。

  3. 初始加载集合后,记下查看的项目 ID,然后订阅集合并传递要观看的 ID 列表(或日期范围)。这将需要一个新的发布函数,该函数采用一组 id,并过滤返回的文档。这种方法可以防止新文档干扰您在屏幕上的内容,并且您仍然会收到评论更改,但您也会收到影响非评论字段的删除和字段更改。

希望其中一种方法可能适合您。

于 2013-03-11T14:55:18.697 回答
0

如果由于某种原因您不希望/不能限制客户端通过发布看到的数据,或者如果可以插入发布时间较早的新帖子并破坏保存,上述解决方案将不起作用。因此,我建议使用不同的解决方案来更直接地实现保存:

打开帖子时,以非反应方式保存已观看帖子的 _id,如下所示:

Session.set('watched',
  _.map(
    Newsfeed.find({}, {
      sort: {updated_time: -1},
      limit: 10,
      reactive: false      //not sure wheather you need both, as @StephenD
    }).fetch(),            // pointed out sth. fetched is non reactive by default
    function (obj) {return obj._id;}
  )
);

和:

Template.group_feed.feed_data = function () {
  return Session.get('watched');
};
Template.group_feed_item.item = function () {
  return Newsfeedd.findOne(this);
};

以及 html 中的一个小更新(其中 with 使您无需定义额外的模板):

<template name="group_feed_item">
  <li>
    {{#with item}} 
      <h1>{{title}} - {{_id}}</h1>
      <div class="comments">
        {{#each comments}}
          <p>{{message}}</p>
        {{/each}}
      </div>
    {{/with}}
  </li>
</template>

最好的,简

于 2013-03-11T16:37:39.420 回答
0

从文档(强调我的) - http://docs.meteor.com/#find

游标是一种反应式数据源。在客户端,当您第一次在响应式计算(例如,模板或自动运行)中使用 fetch、map 或 forEach 检索游标的文档时,Meteor 将注册对底层数据的依赖关系。任何更改游标中文档的集合都会触发重新计算。要禁用此行为,请将 {reactive: false} 作为查找选项传递。

请注意,当指定字段时,只有对包含字段的更改才会在使用此游标的反应式计算中触发观察、观察更改和失效中的回调。谨慎使用字段可以为不依赖于整个文档的计算提供更细粒度的反应性。

于 2014-06-09T20:49:01.140 回答