7

Marionette.CollectionViewのリストをレンダリングする がありますItemViewrender()では、ItemView を使用してRaphaelmodelを使用して SVG を描画します。

Raphael では、キャンバスの高さと幅を指定する必要があり、通常は から取得しthis.$elます。ただし、$el(空の として) には、DOM に追加され、CSS ルールが適用されるまでディメンションがないため、ビューが DOM にあることがわかる<div>までレンダリングを遅らせる必要があります。

問題はMarionette.CollectionView、子ビューがレンダリングされるまで DOM に追加されないことです。の半分を再実装せずに、この動作をオーバーライドするにはどうすればよいCollectionViewですか?

サンプルコード

// Renders a single object.
var ItemView = Marionette.ItemView.extend({
    template: "#item-view-template",
    onRender: function() {
        var svgEl = this.$el.find("div.svg-canvas");
        // Raphael needs the element's width and height, which
        // is 0 until this.$el is in the DOM.
        var paper = Raphael(svgEl.get(0), svgEl.height(), svgEl.width());
        // ... draw some SVG...
    }
});

// Renders a collection of objects.
var ListView = Marionette.CollectionView.extend({
    itemView: ItemView,
    model: MyModel
});

// Main point of entry.
MyApp.show = function() {
    var collection = new MyCollection();
    var listView = new ListView({ collection: collection });
    MyApp.mainRegion.show(listView);
    collection.fetch();
};
4

1 に答える 1

10

onRenderビューがレンダリングされたときにこのメソッドが呼び出されるため、ニーズを処理しませんが、ビューがまだ DOM に追加されていることを保証するものではありません。

onShowそのためには、リージョンにビューを表示するときにリージョンによって呼び出されるメソッドが必要です。問題は、現在の実装ではonShow、直接渡したビュー (この場合はコレクション ビュー) のみを呼び出すことです。そのため、コレクション ビューのすべての子でそのメソッドを呼び出すように onShow を実装する必要があります。


Marionette.CollectionView.extend({
  // ...  

  onShow: function(){
    _.each(this.children, function(childView){
      if (childView.onShow){ childView.onShow(); }
    });
  }
});

それはそれを行う必要があります。呼び出すMyApp.mainRegion.show(listView)onShow、コレクション ビューのメソッドが呼び出され、子に対して呼び出されます (存在する場合)。


コメントの議論によると、親ビューの が呼び出され、アイテムが後でコレクションに追加されたonShow後でも、子ビューのメソッドが呼び出されることを保証する実装が行われます。onShow


ItemView = Marionette.ItemView.extend({
  // ...

  onShow: function(){
    // I am guaranteed to be called from the CollectionView
    // because the CollectionView registers me in a promise
  }
});

CollectionView = Marionette.CollectionView.extend({

  initialize: function(){
    this.onShowCallbacks = new Marionette.Callbacks();
  },

  onShow: function(){
    this.onShowCallbacks.run();
  },

  appendHtml: function(cv, iv){
    cv.append(iv.el);

    // promise to run 'onShow' if it exists
    if (iv.hasOwnProperty("onShow")){
      this.onShowCallbacks.add(iv.onShow);
    }
  }
});

この要点でも利用可能: https://gist.github.com/2872526

于 2012-06-04T23:00:25.293 に答える