2011-12-27 73 views
1

試圖創建一個待辦事項示例應用程序來攪亂骨幹。我無法弄清楚爲什麼點擊事件複選框沒有觸發。這裏是我的TaskCollection,TaskView和TaskListView代碼:查看事件不會觸發創建的元素?

$(document).ready(function() { 

Task = Backbone.Model.extend({}); 

TaskCollection = Backbone.Collection.extend({ 
    model: 'Task' 
}); 

TaskView = Backbone.View.extend({ 
    tagName: "li", 
    className: "task", 
    template: $("#task-template").html(), 
    initialize: function(options) { 
     if(options.model) { 
      this.model = options.model 
     } 
     this.model.bind('change',this.render,this); 
     this.render(); 
    }, 
    events: { 
      "click .task-complete" : "toggleComplete" 
    }, 
    render: function(){ 
     model_data = this.model.toJSON(); 
     return $(_.template(this.template, model_data)); 
    }, 
    toggleComplete: function() { 
     //not calling this function 
     console.log("toggling task completeness"); 
    } 
}); 

TaskListView = Backbone.View.extend({ 
    el: $("#task-list"), 
    task_views: [], 
    initialize: function(options) { 
     task_collection.bind('add',this.addTask,this); 
    }, 
    addTask: function(task){ 
     task_li = new TaskView({'model' : task}); 
     this.el.append(task_li.render()); 
     this.task_views.push(task_li); 
    }, 
}); 
}); 

模板任務:

<script type='text/template' id='task-template'> 
    <li class="task"> 
     <input type='checkbox' title='mark complete' class='task-check' /> 
     <span class='task-name'><%= name %></span> 
     </li> 
</script> 

我似乎無法弄清楚,爲什麼toggleComplete事件不會觸發任務。我怎樣才能解決這個問題?

+0

我的答案是否適合您或者不清楚? – Wieczo 2011-12-30 12:32:27

回答

2

這裏的問題是,當你創建一個新的視圖的骨幹事件只設置到視圖(this.el)的元素。但在你的情況下,元素不被使用。因此,您在視圖中擁有tagName:li屬性,它允許骨幹創建新的li元素,但不使用它。您所返回的是從您的模板創建的新列表元素,但不是元素骨幹網創建的,您可以通過訪問this.el

因此,您必須手動將事件添加到由模板使用jQuery創建的元素中,或者添加模板innerHTML來你的元素:

(this.el.html($(_.template(this.template, model_data))) 
0

嘗試更改使用.bind()使用.live()設置偵聽器的行。最重要的區別是,當您想要將偵聽器綁定到頁面加載後創建的元素時,應使用.live()。

最新版本的jQuery避免了這種醜陋現象,並簡化了用於設置事件偵聽器的方法。

+0

骨幹實際上是在引擎蓋下使用'委託' – blockhead 2011-12-27 20:08:06

0

你的事件被綁定到一類.task-complete但你的複選框類是.task-check

+0

改變了(並更新了我的問題),仍然沒有解決問題。 – GSto 2011-12-27 20:44:19

0

嘗試修改渲染函數來調用delegateEvents()像這樣:

render: function(){ 
    model_data = this.model.toJSON(); 
    this.el = $(_.template(this.template, model_data)); 
    this.delegateEvents(); 
    return this.el; 
}, 

你真的很會更好改變你的模板不包括李和然後返回this.el而不是替換它,但是如果你想讓這些事件起作用,你需要以這種或那種方式使這個.el成爲根元素; delegateEvents()重新附加事件的東西,所以當你改變this.el應該解決這個問題。

0

@AndreasKöberle正確回答了你的問題。你需要分配一些東西給this.el使事件工作。

我改變了你的模板和你的TaskView#render()函數。 此JSFiddle已應用更改。

新的渲染功能

render: function(){ 
    var model_data = this.model.toJSON(); 
    var rendered_data = _.template(this.template, model_data); 
    $(this.el).html(rendered_data); 
    return this; 
} 

建議的render()返回此。

TaskListView#addTask函數中的一行從this.el.append(task_li.render());更改爲this.el.append(task_li.render().el);

模板變化

由於我們是在渲染()函數中使用this.el,我們必須從模板中刪除<li>標籤。

<script type='text/template' id='task-template'> 
    <input type='checkbox' title='mark complete' class='task-complete' /> 
    <span class='task-name'><%= name %></span> 
</script>