现在我对 Backbone 有了更好的了解(我希望),我一直在用细齿梳浏览这个应用程序,以了解它是如何工作的:
https://github.com/ccoenraets/nodecellar/tree/master/public
让我难过的最新事情是 windetails.js 中的 EL 标签(这里:https ://github.com/ccoenraets/nodecellar/blob/master/public/js/views/winedetails.js )
我将在下面粘贴相关代码,但我的问题是如何分配此视图的 EL 属性?正如您将在视图定义中注意到的那样,没有定义 EL 标记,也没有分配 idTag 或 className 属性。但是,我在 firebug 中验证了该视图确实在侦听 DOM 中间的 DIV 标签(实际上就在内容 DIV 的下方)。那么它是如何附着在那里的呢?如果不是这样,Click 处理程序将无法正常工作,但确实如此。之前所有看起来都是以相同方式创建的视图都具有未附加的 EL 属性。
window.WineView = Backbone.View.extend({
initialize: function () {
this.render();
},
render: function () {
$(this.el).html(this.template(this.model.toJSON()));
return this;
},
events: {
"change" : "change",
"click .save" : "beforeSave",
"click .delete" : "deleteWine",
"drop #picture" : "dropHandler"
},
change: function (event) {
// Remove any existing alert message
utils.hideAlert();
// Apply the change to the model
var target = event.target;
var change = {};
change[target.name] = target.value;
this.model.set(change);
// Run validation rule (if any) on changed item
var check = this.model.validateItem(target.id);
if (check.isValid === false) {
utils.addValidationError(target.id, check.message);
} else {
utils.removeValidationError(target.id);
}
},
beforeSave: function () {
var self = this;
var check = this.model.validateAll();
if (check.isValid === false) {
utils.displayValidationErrors(check.messages);
return false;
}
this.saveWine();
return false;
},
saveWine: function () {
var self = this;
console.log('before save');
this.model.save(null, {
success: function (model) {
self.render();
app.navigate('wines/' + model.id, false);
utils.showAlert('Success!', 'Wine saved successfully', 'alert-success');
},
error: function () {
utils.showAlert('Error', 'An error occurred while trying to delete this item', 'alert-error');
}
});
},
deleteWine: function () {
this.model.destroy({
success: function () {
alert('Wine deleted successfully');
window.history.back();
}
});
return false;
},
dropHandler: function (event) {
event.stopPropagation();
event.preventDefault();
var e = event.originalEvent;
e.dataTransfer.dropEffect = 'copy';
this.pictureFile = e.dataTransfer.files[0];
// Read the image file from the local file system and display it in the img tag
var reader = new FileReader();
reader.onloadend = function () {
$('#picture').attr('src', reader.result);
};
reader.readAsDataURL(this.pictureFile);
}
});
编辑 有很多关于这种模式的讨论: $(x).append(v.render().el)
如果我错了,有人纠正我,但据我所知,这是一个 Jquery 调用,用于使用 v 对象的“el”属性的内容更新“x”标记处的 DOM(在调用 render 之后)。即使之前没有设置“el”属性并且是“未附加的 div”,只要它之前从渲染方法写入了有效内容,这种技术也应该将内容呈现到 DOM 中。
然而,在将内容写入 DOM 之后,“el”属性仍然是一个未附加的 div,直到它被直接分配给 DOM。
我通过 Firebug 验证了这个 Backbone 应用程序有两个视图,它们都以这种方式呈现,并且都具有未附加的 div el 属性。这些是 wineList 视图和 homeView。但是,第三个视图是 WineDetail 视图,它似乎没有未附加的 EL 属性。它的 EL 属性似乎已附加,而且还有助于点击事件。我的问题是这个 EL 属性是如何附加并分配给 DOM 的?