gpt4 book ai didi

javascript - 这个点击处理程序如何分配给 DOM 元素?

转载 作者:行者123 更新时间:2023-11-28 01:58:44 25 4
gpt4 key购买 nike

现在我对 Backbone 有了更好的了解(我希望),我一直在仔细研究这个应用程序以了解它的工作原理:

https://github.com/ccoenraets/nodecellar/tree/master/public

最近让我困惑的是windetails.js 中的EL 标记(此处: https://github.com/ccoenraets/nodecellar/blob/master/public/js/views/winedetails.js )

我将在下面粘贴相关代码,但我的问题是如何分配此 View 的 EL 属性?您会注意到,在 View 定义中没有定义 EL 标记,也没有分配 idTag 或 className 属性。不过,我在 firebug 中验证了该 View 确实正在监听 DOM 中间的 DIV 标记(实际上就在内容 DIV 的下方)。那么它是如何附着在那里的呢?如果不是这样,单击处理程序将无法正常工作,但它可以正常工作。所有以前的 View 看起来都是以相同的方式创建的,并且具有未附加的 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(调用渲染后) 。即使之前未设置“el”属性并且是“未附加的 div”,只要该技术之前已从渲染方法写入了有效内容,该技术就应该将内容渲染到 DOM 中。

但是,在将内容写入 DOM 后,“el”属性仍然保持为未附加的 div,直到将其直接分配给 DOM。

我通过 Firebug 验证,此 Backbone 应用程序有两个 View ,它们以这种精确方式呈现,并且都具有未附加的 div el 属性。它们是 wineList View 和 homeView。然而,第三个 View 是 WineDetail View ,它似乎没有独立的 EL 属性。它的 EL 属性似乎已附加,并且正在促进点击事件。我的问题是这个 EL 属性是如何附加并分配给 DOM 的?

最佳答案

通过查看 Backbone.View 的内部结构可以找到答案。

查看构造函数:

  var View = Backbone.View = function(options) {
this.cid = _.uniqueId('view');
this._configure(options || {});
//this function is responsible for the creation of the `this.el` property.
this._ensureElement();
this.initialize.apply(this, arguments);
this.delegateEvents();
};

Ensure that the View has a DOM element to render into. If this.el is a string, pass it through $(), take the first matching element, and re-assign it to el. Otherwise, create an element from the id, className and tagName properties. http://backbonejs.org/docs/backbone.html#section-133

现在我们知道了 this.el 来自哪里,看看 events docs看看它是如何处理的。

该 View 在 main.js 中实例化

$('#content').html(new WineView({model: wine}).el);

编辑:

None of which explains how the View Object's EL property is set and and how the click trigger works.

我会尽力解释得更好:

this.el 是通过在 Backbone.View 构造函数中调用 this._ensureElement 创建的。我们还可以看到,this.render 是从实例化时运行的 initialize 函数调用的。我们可以看到,在 this.render 中,我们将 this.el 的内容设置为将 this.template 应用到模型的结果。

现在,在 Backbone.View 的初始化过程中,在调用 this.initialize 之后,events 配置由调用 this.delegateEvents。这是使用给定选择器附加事件监听器的地方。 请注意,大多数事件将直接附加到 this.el 并利用事件委托(delegate),而不是直接将事件附加到子元素上。

此时,我们剩下一个 this.el,其中包含所有必要的标记并设置了所有事件监听器。然而,this.el 仍然不是 DOM 的一部分。

但是从代码中我们可以看到,在 View 实例化之后,this.el 将作为 #content 元素的子元素附加到 DOM:

$('#content').html(new WineView({model: wine}).el);

关于javascript - 这个点击处理程序如何分配给 DOM 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18731517/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com