I'm trying to play around with Backbone JS and so far everything seems to be making sense and working smoothly.
However with the code below, my custom events do not seem to be firing. Anything in the below code stand out as to why that might be? Do I need to "initialize" anything in the View? Any other pointers on the code/structure would be cool as well. Below is my full 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>
el: $(".content")
Try this:
var appview = new AppView({ el:$(".content"), collection: data });
You cannot call a jQuery there because the DOM is not yet created. You must do it when the view is loaded either as my example or in the initialize.
Additionally, for your events to work, you must bind your content in the render function to this.el. Events are all bound to the element you specify, so it follows that you need to have your event-generating elements bound as children to the element which acts as the delegator.
The approved answer has a drawback. You can not be very dynamic if you set { el: $(".content") }. It is not possible to reuse ".content"-Element inside your DOM. As soon as you call remove() on this view $(".content") will be gone too.
I use another parameter to pass that information:
{ renderTarget: $("#content") }.
and insert my view into the DOM at start of render:
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;
}
精彩评论