2011-04-28 112 views
28

我想玩骨幹JS和迄今爲止一切似乎是有道理的,工作順利。骨幹JS查看事件不燒?

但是,下面的代碼,我的自定義事件似乎並沒有被解僱。以下代碼中的任何內容都突出了爲什麼這可能是?我需要在視圖中「初始化」任何東西嗎?代碼/結構上的其他指針也會很酷。以下是我的完整的JS/HTML。

JS

var Todo = Backbone.Model.extend({}); 

var TodoCollection = Backbone.Collection.extend({ 

    model: Todo, 
    url: '/Home/Todos' 

}); 

var AppView = Backbone.View.extend({ 

    // where it should listen, required? 
    el: $(".content"), 

    events: { 
     "keypress #new-todo": "enter" 
    }, 

    initialize: function() { 
     // _.bindAll(this, "render", "createOnEnter"); 
     // this.collection.bind("all", this.render); 
    }, 

    hi: function() { 
     alert('ohai'); 
    }, 

    render: function() { 
     var lis = ''; 
     $.each(this.collection.models, function() { 
      lis += '<li>' + this.get('Text') + '</li>'; 
     }); 
     $('#todo-list').append(lis); 
     return this.el; 
    }, 

    enter: function (e) { 
     alert('hi'); 
    } 

}); 


var TodoController = Backbone.Controller.extend({ 

    routes: { 
     "": "todos" 
    }, 

    initialize: function (options) { }, 

    todos: function() { 
     var todolist = new TodoCollection(); 
     todolist.fetch({ 
      success: function (data) { 
       var appview = new AppView({ collection: data }); 
       appview.render(); 
      } 
     }); 
    } 

}); 

$(function() { 
    window.app = new TodoController(); 
    Backbone.history.start(); 
}); 

HTML

<div id="todoapp"> 
    <div class="content"> 
     <input id="new-todo" placeholder="What needs to be done?" type="text" /> 
     <div id="todos"> 
      <ul id="todo-list"> 
      </ul> 
     </div> 
     <a href="#">say hey</a> 
    </div> 
</div> 

回答

37
el: $(".content") 

試試這個:

var appview = new AppView({ el:$(".content"), collection: data }); 

不能調用一個jQuery那裏,因爲尚未創建的DOM。您必須在視圖以我的示例或初始化加載時執行此操作。

+1

感謝您的回答。我仍然有點困惑,爲什麼DOM不會在那個時候創建​​。我在底部啓動控制器,並將其包裝在一個文件準備就緒的通話中。然後我的控制器報道AppView,所以在那個時候不是第一次調用'el'? – aherrick 2011-04-30 09:53:17

+5

var AppView = Backbone.View.extend({})在瀏覽器讀取它時評估。您在文檔ready調用中實例化它,但由於_el_不是函數,它將作爲擴展的一部分進行評估。 – Julien 2011-05-02 13:20:19

+3

有人可以解釋爲什麼Backbone.js Todo示例在創建AppView時不需要傳入參數?他們在todo.js的頂部有這樣的註釋,「//在DOM準備就緒後,使用'jQuery.ready'加載應用程序:」,但我沒有看到他們做了任何事情來確保DOM已經準備就緒。謝謝。 – Quentamia 2011-05-25 15:25:06

16

此外,爲了讓您的事件發揮作用,您必須將渲染函數中的內容綁定到this.el.事件都與您指定的元素綁定,因此您需要將事件生成元素作爲子元素綁定到充當委派者的元素。

+3

我喜歡這個評論兩次,但我不能,這正是我的問題,10倍! – 2011-12-12 21:28:38

+0

隨着Backbone API的更新,現在也發生了變化。現在有一種方法可以動態設置el,如果使用該方法,那麼delegateEvents()會被該函數自動調用。 – 2012-03-01 19:21:16

+0

我不太瞭解骨幹,但我認爲這可以通過不指定el屬性和在$('。content')渲染函數內部解決。wrap(this.el); – BishopZ 2012-07-13 21:32:55

1

覈準的答案有一個缺點。如果您設置{el:$(「。content」)},您就不會變得非常動態。無法在您的DOM內重複使用「.content」元素。只要你在這個視圖上調用remove(),$(「。content」)就會消失。

我用另一個參數來傳遞信息:

{ renderTarget: $("#content") }. 

,並插入我的觀點到DOM在渲染的開始:

initialize: function (options) { 
    options = options || {}; 
    this.renderTarget = options.renderTarget || this.renderTarget; 
}, 
render: function() { 
    if (this.renderTarget) { 
     $(this.renderTarget).html(this.el); 
    } 
    ... render stuff into $(this.el) ... 
    return this; 
}