2

私は本当に奇妙な問題を抱えています。名前空間構造としても機能する「ルート」ビューを実装しようとしています。codeschool.com コースのパート II で導入されたのと同じ原則。このルートビューで、イベント「クリックボタン」をキャッチしたいのですが、それが問題です。ボタンをクリックしても何も起こりませんでした。

window.App = new (Backbone.View.extend({
  el: $("#app"),
  Collections: {},
  Models: {},
  Views: {},
  Routers: {},
  events: {
    'click button' : function(e) {
      alert("Thank god!");
    }
  },
  render: function(){
    //for test purposes
    console.log($("#app").find("button"));
    console.log(this.$el.find('button'));
  },
  start: function(){
    this.render();
    new App.Routers.PostsRouter();
    Backbone.history.start({pushState: true});
  }
}))();



$(document).ready(function() { App.start() });

HTMLはこんな感じ

<body>
    <div id="app">
        <div id="posts"></div>

        <button>Click me</button>
    </div>
</body>

そして本当に奇妙なのは、render 関数の console.log からの出力です。両方のセレクターは同じで、コンテキストも同じですが、どこに問題がありますか?

console.log($("#app").find("button")); //this returns correct button
console.log(this.$el.find('button')); //this returns 0 occurences (WTF?)

編集: で少し変更した後el: "#app"でも、同じ問題が発生します。問題は(@nemesvのおかげで)DOMがロードされる前にこのクラスをインスタンス化することでした。ただし、DOM がロードされた後にインスタンス化することはできません。これは、その名前空間構造を使用できないためです (例: App.Model.Post = Backbone.Model.extend() )。しかし、この「名前空間構造を持つメイン ビュー」は、ある種の優れた実践として codeschool.com コースで紹介されています。そこに解決策がありますhttp://jsfiddle.net/BckAe

4

1 に答える 1

3

jqueryセレクターとしてを指定elしましたが、オブジェクトリテラル内にあるため、DOMがロードされる直前に評価されます。

したがって、el: $("#app"),は何も選択しません。

elこれは、セレクターを含む文字列として初期化できるバックボーン機能の1つを使用して解決できます。

したがって、el宣言を次のように変更します。

el: "#app"

DOMがロードされる前にビューをインスタンス化するため、クリックイベントはトリガーされないため、バックボーンはイベントの委任を実行できません。

したがって、ビューの宣言と作成を2つのステップに分ける必要があります。そして、DOMがロードされたときにのみビューをインスタンス化します。

var AppView = Backbone.View.extend({
   el: "#app",  
   //...
});

$(document).ready(function() 
{ 
    window.App = new AppView();
    App.start() 
});

デモ:JSFiddle

于 2013-02-12T09:30:09.453 に答える