7

Signalr ハブを使用して、サーバー上のイベントをサブスクライブしています。どのようなイベントがハブにディスパッチされ、アイテムが Marionette CollectionView に正常に追加されますか。これは、テーブルにレンダリングされます。

Because the table of events is essentially a blotter, I'd like the events in reverse order and preferably only keep n-number of events.

Can Backbone 'automatically' re-render a collection in reverse order?

4

8 に答える 8

11

逆の順序でコレクションを実行するには、通常、次のような構造を使用します。

_.each(collection.last(collection.length).reverse(), function(model){ });
于 2012-12-14T10:35:11.057 に答える
8

このトピックに関するスレッドがhttps://github.com/marionettejs/backbone.marionette/issues/78にあります。

@breischlが指摘したように、Backboneはコンパレータを定義するとコレクションをソートしたままにしますが、順序が変更されたときにMarionetteはCollectionViewを自動的に再レン​​ダリングしません。実際、Marionette はaddコレクションのイベントをリッスンし、新しい ItemViewを追加します。

CollectionViewアイテムを常に新しい順に表示し、追加された新しいアイテムをappendedではなく先頭に追加する場合は、次のようにappendHtmlメソッドをオーバーライドします。CollectionView

var MyCollectionView = Backbone.Marionette.CollectionView.extend({
  appendHtml: function(collectionView, itemView){
    collectionView.$el.prepend(itemView.el);
  }
});

コメントで@diraが言及したように特定の場所に挿入できるようにしたい場合は、sberrymanによるgithubの上記のリンクに投稿された解決策があり、便宜上ここで再現します(免責事項:以下のコードはテストしていません個人的に):

appendHtml を次のように変更します。

appendHtml: function(collectionView, itemView) {
  var itemIndex;
  itemIndex = collectionView.collection.indexOf(itemView.model);
  return collectionView.$el.insertAt(itemIndex, itemView.$el);
}

そして、以下を追加して拡張し、機能jQueryを提供します。insertAt

(function($) {
  return jQuery.fn.insertAt = function(index, element) {
    var lastIndex;
    if (index <= 0) return this.prepend(element);
    lastIndex = this.children().size();
    if (index >= lastIndex) return this.append(element);
    return $(this.children()[index - 1]).after(element);
  };
})(jQuery);
于 2012-05-09T04:46:04.013 に答える
1

Backbone.View通常、レンダリングは「サブクラス」で行われます。だからあなたは次のようなものを持っています:

render: function() {
  this.collection.each( function(model) {
    // some rendering of each element
  }, this );
}

this.collectionおそらくBackbone.Collectionサブクラスであるため、underscore.jsメソッドを使用するだけで、好きな順序で取得できます。

this.collection.reverse().each( ... )
this.collection.sort( function(m) { ... } ).each( ... )

等。

もちろん、バックエンドから単一の要素を取得しているので、全体を再レンダリングせずに適切な場所に挿入したいと考えています。したがって、その場合は、古い学校に行って、ソートキーをrel属性またはdata要素の属性として挿入し、それを(または同様の)メソッドinsertAfterのjQueryと同様に使用します。renderNewItem

于 2012-03-19T13:29:06.113 に答える
1

あなたが説明したことから、コレクションを逆の順序で再レンダリングする必要はありません。そのビューのコレクションにイベントを追加し、追加addしたアイテムをレンダリングしてテーブルに追加する関数を呼び出すだけです。

this.collection.on('add', this.addItem);
于 2012-03-20T05:09:04.310 に答える
1

Backbone は自動的にコレクションをソート順に保持します。デフォルト以外の並べ替えを使用する場合comparator()は、コレクションに関数を定義すると、代わりにそれが使用されます。コンパレータは、1 つまたは 2 つの引数を取ることができます。詳細については、バックボーンのドキュメントを参照してください。

その後、コレクションを .each() ループでレンダリングすると、正しい順序で出力されます。ただし、ソートされた順序でビューに新しいアイテムを追加するのはあなた次第です。

于 2012-03-20T00:00:57.370 に答える
0

コレクション内のモデルを次のように逆にすることができます...

this.collection.models = this.collection.models.reverse()
于 2014-12-10T06:29:27.923 に答える
0

BackBone はコレクションの逆反復をサポートしていないため (コレクションを逆にしたり、最悪の場合は並べ替えたりするのは単にリソースを浪費するだけです)、最も簡単で最速の方法はfor、コレクション内のモデルに対してインデックスを減少させるループを使用することです。

for (var i = collection.length - 1; i >= 0; i--) {
    var model = collection.models[i];

    // your logic
}

Underscore を使用してコレクションをソートまたは反転するほどエレガントではありませんが、パフォーマンスははるかに優れています。ここでさまざまなループを比較して、classic for の代わりに foreach を作成するコストを確認してください。

于 2015-09-23T12:47:13.263 に答える
0

アンダースコアの代わりにlodashを使用する場合は、次のようにすることもできます。

_(view.collection.models).reverse();
于 2015-03-18T07:23:37.540 に答える