1

Backbone.Viewコレクションをスクロール可能なリストとしてレンダリングする必要があるに取り組んでいます。

clientWidth初期レンダリングの一部として、ビューがレンダリングされた後にのみ使用できるいくつかのレイアウトプロパティ(例)にアクセスする必要があります。

私の問題は、ビューがDOMに追加されたことをどのように知ることができるかということです。


を使用してBackbone.View、ビューをDOMにアタッチするには通常2つの方法があります。

  1. ビューを作成>レンダリング>アタッチ:

    view = new MyList().render()
    $('#dummy').append(view.$el)
    
  2. ビューを作成し、インプレースでレンダリングします。

    new MyList({el: '#dummy'}).render()
    

注:(1)と(2)は完全に同等ではないことを私は知っています、それはポイントではありません。


私のリストが次のように定義されていると考えてみましょう。

class MyList extends Backbone.View
    render: ->
        @$el->html( ... )
        @

    layout: ->
        max = $el.scrollWidth - $el.clientWidth
        # ... disable / enable scrolling arrows based on max ...

MyListがDOMにアタッチされた後にlayout()が呼び出されることをどのように確認しますか?

4

3 に答える 3

9

私はまさにこの問題に直面しており、役立つパターンがあります。Backbone はツールを提供しますが、その使用方法については説明しません。作業を行う際に、適切なパターンを確立することが非常に重要です。これに役立つ 2 つの異なるパターンを使用しました。

1) アプリケーションの動作方法によっては、ビューをレンダリングして DOM にアタッチした後、ビューで常にattached()メソッドを呼び出したり、イベントをトリガーしたりすることを簡単または困難にすることができます。attached私の場合は、それを 1 か所で処理できるアーキテクチャを作成したので簡単でした。

2) 常にレンダリングの直後に要素を DOM にアタッチする場合、特に、非同期コールバック内でアタッチを延期せずにレンダリングした後はいつでも、render() 関数内で、layout()または実行する必要があるものへの呼び出しを延期できます。付けた後。そのようです:

var MyList = Backbone.View.extend({
  render: function() {
    /* rendering logic goes here */

    // Notice that the timeout is 0 - you can actually not even pass this argument
    // but I wanted to emphasize that there is no delay given.
    setTimeout(this.layout, 0);

    return this;
  },

  layout: function() {
    // This code won't be run until after this.el is attached to the DOM
  }
});

var view = new MyList().render();
$('#dummy').append(view.$el);

Javascript は常にシングル スレッドです。I/O は非同期で実行できますが、実際に JS エンジンからの時間を必要とするものは、他の JS コードと並行して実行できません。setTimeout()最後の引数なしで、またはその値を指定して呼び出すと0、現在実行中のコードが終了した後、できるだけ早く実行するためにキューに入れられます。

呼び出し後すぐに常に DOM にアタッチするパターンに従うと、この事実を利用できます。つまりrender()、現在実行中のコードの実行が終了し、JS エンジンに制御を戻して次にキューに入れられているものを実行する前の任意の時点です。によってキューに入れられた関数setTimeout(func, 0)が実行されるまでに、ビューが DOM にアタッチされていることがわかります。これは what _.defer()does と同じことですが、説明したいと思います。

繰り返しますが、パターンを確立することは非常に重要です。一貫性がなく、アプリケーション内でパターンを確立していない場合、保証はなく、このメカニズムを信頼できなくなります。他の方法で確立できる可能性がある他のメカニズムも信頼できなくなります。お役に立てれば!

于 2013-04-11T07:00:02.650 に答える
3

それは一見難しい問題です。DOM Mutation Eventsがありますが、知る限り、これらはクロスブラウザーで実装されておらず、非推奨です。Mutation Observersはそれを行う新しい方法のようですが、互換性についてはよくわかりません。

確実ですが、費用がかかり面倒な方法は、本体が祖先チェーンのどこかにあるかどうかを確認するためにポーリングすることです。

whenInserted = function ($el, callback) {
  check = function () {
    if ($el.closest('body').length) { // assuming a jQuery object here
      callback();
    } else {
      setTimeout(check, 100);
    }
  };
  check();
};
于 2012-09-05T16:44:22.280 に答える