1

Meteorで構築したいニュースフィードのアイデアがありますが、ニュースフィード自体を一定にする方法を見つけるのに少し苦労しています。これは反応的ではありませんが、サブアイテムを更新します(コメント、いいねなど)更新されるとすぐに。

すべてを1つのコレクションに保存しているので、可能であればそのままにしておきたいと思います。したがって、コレクションは次のように設定されます。

[
    {
        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

ここには 2 つのオプションがあります。(疑似コードには coffeescript を使用します)

  • observeChangesを使用します。

    NewsCursor = NewsItems.find()
    NewsCursor.observeChanges
      changed: (id, fields) ->
        if fields.comments
          Session.set ("commentsForId"+id), fields.comments
    
  • データを 2 つのコレクションに分割します。1 つは投稿用、もう 1 つはコメント用です。

これらのいずれかを行わない場合、{{isolate}} は役に立ちません。現在のデータ設定では、Meteor は投稿が変更されたかどうかを確認し、変更されたときにテンプレートを更新します。どの部分が変更されたかを追跡しません。

于 2013-04-25T12:37:06.977 に答える
0

問題は、カーソルではなく配列を返していることだと確信しています。Sparkは2つで動作が異なるようです。

.fetch()フィードクエリの最後からを削除します。

このようなものがどのように機能するかについての詳細は、 http: //www.eventedmind.com/でChrisMatherのすばらしいプレゼンテーションを参照することを強くお勧めします。

具体的には、スローモーションでの反応性に関するものは、配列とカーソルの違いを示しています:http: //www.eventedmind.com/posts/meteor-ui-reactivity-in-slow-motion

更新:私の元の答えでは、問題を完全には理解していませんでした-謝罪なので、fetch()を削除することについての少しはあなたを助けません。探索したいオプションがいくつかあります。

  1. Meteor.observeまたはMeteor.observeChangesを使用して、コメントフィールドへの変更を監視し、コードでDOMを更新しました(「手動」)。

  2. 元のコレクションからのコメントのみを公開するカスタムコレクションをサーバー側で作成します。したがって、mongoに格納されているデータモデルを変更することはお勧めしません。別のビューを公開するだけです。このようにすると、コメントを更新するためにテンプレートを引き続き使用する方が簡単な場合があります。

  3. コレクションを最初にロードした後、表示されたアイテムIDをメモし、コレクションをサブスクライブして、監視するIDのリスト(または日付範囲)を渡します。これには、IDの配列を取得し、返されたドキュメントをフィルタリングする新しい公開関数が必要になります。このアプローチにより、新しいドキュメントが画面に表示されている内容を乱すのを防ぎ、コメントの変更を取得できますが、コメント以外のフィールドに影響を与える削除やフィールドの変更も取得できます。

うまくいけば、これらのアプローチの1つがあなたの法案に合うかもしれません。

于 2013-03-11T14:55:18.697 に答える
0

ドキュメントから(強調鉱山) - http://docs.meteor.com/#find

カーソルはリアクティブ データ ソースです。クライアントでは、リアクティブ計算 (テンプレートや自動実行など) 内で fetch、map、または forEach を使用してカーソルのドキュメントを初めて取得するときに、Meteor は基になるデータへの依存関係を登録します。カーソル内のドキュメントを変更するコレクションへの変更は、再計算をトリガーします。この動作を無効にするには、find のオプションとして {reactive: false} を渡します。

フィールドが指定されている場合、含まれているフィールドへの変更のみが、このカーソルを使用するリアクティブ計算のobserve、observeChanges、および無効化でコールバックをトリガーすることに注意してください。フィールドを慎重に使用すると、ドキュメント全体に依存しない計算に対して、よりきめ細かい反応性が可能になります。

于 2014-06-09T20:49:01.140 に答える
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

なんらかの理由で、パブリッシュを使用してクライアントに表示されるデータを制限したくない/制限できない場合、または以前の投稿時間の新しい投稿が挿入されて保存が破棄される可能性がある場合、上記のソリューションは機能しません。したがって、保存をより直接的に達成するための別の解決策を提案します。

投稿を開くと、監視されている投稿の _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 に答える