1

関連するすべてのコメントが見つかるまで、各コメント/サブコメントで再帰的に繰り返される、トピック、25 のコメント、およびコメントごとに最大 5 つのサブコメントをロードしたいと考えています。

現在、角度ディレクティブを使用して、コメントに子が含まれるたびに再帰的にサブスクライブしてローカル コレクションに追加しています。これは非常にうまく機能しますが、最初の 25 個のコメントをロードしてから、その子をロードし、次にその子などをロードするまでに (予想されるように) 多少の遅延があります。

この問題は、一度にページをロードするだけであれば問題ありません。無限スクロールを使用し、最初の 25 コメント制限を増やすと問題になります。サブコメントが消え、再度読み込まれると再び表示されるため、ページが少し上下にジャンプします。

ローカル クライアントに送信する前にすべてのコメントを再帰的に検索する方法を考えていたので、トピックごとに複数回の往復を行う必要はありません。

ck-gaming.comでデモをロードしました

一番下までスクロールすると、さらに読み込まれ、サブコメントがページに再読み込みされると、ジャンプするのがわかります。

私が考えることができる 2 つのオプションは、解決を使用してページをロードする前にすべてのコレクションを待機するか、再帰的な発行を使用して最初にすべてを取得することです。

考え?アイデア?

わかりました、できれば考えてみたい最初の試みです。

パブリッシングについては、同じコレクションからのパブリッシュをより簡単にするために、 publish-compositeを使用することにしました。

私が書いた出版物のために:

Meteor.publishComposite('oneDiscussion', function (slug, options) {

var query = {};
query.find = function () {
    return Discussions.find({ slug: slug }, { limit: 1 });
};

var mainChildQuery = Comments.find({ slug: slug }, { limit: 1 });

query.children = [];
query.children[0] = {};
query.children[0].find = function (discussion) {
    return mainChildQuery;
};
query.children[0].children = [];
query.children[0].children[0] = {};
query.children[0].children[0].find = function (comment) {
    return Meteor.users.find({ _id: comment.author.id }, { limit: 1, fields: { profile: 1, roles: 1, createdAt: 1, username: 1 } });
};
query.children[0].children[1] = {};
query.children[0].children[1].find = function (parent) {
    Counts.publish(this, 'numberOfComments', Comments.find(
        { parent_id: parent._id }
        ), { noReady: true });
    console.log(options)
    return Comments.find({ parent_id: parent._id }, options);
};

//  var parentQuery = Comments.find({ slug: slug });
var parent = mainChildQuery.fetch();
var children = Comments.find({ parent_id: parent[0]._id }, { limit: 25 }).fetch();

var childrenIds = _.pluck(children, '_id');


var getChildren = function (children_ids, thisParent) {

    var i = 0;
    thisParent.children = [];

    var recursive = function getEm(children, parent) {
        _.each(children, function (id) {

            //              parent.children[i] = new Children(id);
            var query = Comments.find({ parent_id: id }, { limit: 5, sort: { date: -1 } });
            parent.children[i] = {
                find: function () {
                    return Comments.find({ parent_id: id }, { limit: 5, sort: { date: -1 } });
                }
            };


            var children1 = query.fetch();
            var newChildrenIds = _.pluck(children1, '_id');
            i++;
            if (newChildrenIds.length > 0) {
                getEm(newChildrenIds, parent);
            }
        });
    }

    recursive(children_ids, thisParent);

};

getChildren(childrenIds, query.children[0].children[1]);
return query;

});

これまでのところ問題なく動作しているようですが、デスクトップで実行すると、思ったほどパフォーマンスが高くありません。展開して、オンラインで違いがあるかどうかを確認します。家に帰ってライブサイトを更新できたら更新します。誰かが私が書いたものに何か問題を見つけることができれば、それは大歓迎です.

4

1 に答える 1

0

私は最善の解決策だと思うものを思いつきました。上記の機能を改善しましたが、これまでのところ、結果を本当に楽しんでいます。

パブリッシュ機能は次のとおりです。

Meteor.publishComposite('comments', function (item_id, options) {
    /**
     * TODO: Add query to find a user for each comment.
     */
    /**
     * Start building our query.
     * Add the latest 25 (depending on options) child comments of the viewed item
     * to the query.
     */
    var query = {
        find: function () {
            return Comments.find({ parent_id: item_id }, options);
        }
    };
    // Query the database for the first 25? comments, we'll need their _id's
    var mainChildren = Comments.find({ parent_id: item_id }, options).fetch();
    // pluck the id's from the initial comments
    var mainChildrenIds = _.pluck(mainChildren, '_id');

    /**
     * Builds the remaining query based on the id's plucked from the children
     *  above.
     * @param childrens_id The id's we just plucked from the above query
     * @param thisParent This is the parent query
     */
    var getChildren = function (children_ids, parentQuery) {
        // initiate i to 0
        var i = 0;
        // add a child array to the current parent query.
        parentQuery.children = [];
        var recursive = function getem(children, parent) {
            _.each(children, function (id) {
                var query = Comments.find({ parent_id: id }, { limit: 5, sort: { date: 1 } });
                parent.children[i] = {
                    find: function () {
                        return query;
                    }
                };
                var children1 = query.fetch();
                var newChildrenIds = _.pluck(children1, '_id');
                i++;
                if (newChildrenIds.length > 0) {
                    getem(newChildrenIds, parent);
                }
            });
        };
        // recursively build the query if there are children found.
        recursive(children_ids, parentQuery);
    };
    // initiate the query build function
    getChildren(mainChildrenIds, query);
    return query;
});

ここで GitHub で入手できるサンプルアプリを作成しました

ここで meteorpad で実行しているのを見ることができます

それは何をしますか

関数が行うのは、publishComposite クエリを作成し、子 ID がある限り、子 ID を再帰的にループすることだけです。子供がいなくなると止まります。

それを使用する

parent_id フィールドを持つコメント (または入れ子になっているもの) のコレクションが必要です。このフィールドには、親投稿 ID、親アイテム ID (レビュー/コメントでストアを作成する場合) のいずれかが入力されます。もちろん、親の投稿 ID は、コメントしているコメントまたは投稿になります。詳細については、例を参照してください。

于 2015-08-12T21:29:10.603 に答える