Backbone.js - 给定一个元素,我如何获得视图? [英] Backbone.js - Given an element, how do I get the view?
问题描述
我创建了一堆 Backbone.js 视图.每个视图都有一个关联元素 (view.el
).
I've created a bunch of Backbone.js views. Each view has an associated element (view.el
).
给定页面上的一个元素——脱离视图的上下文——获取该元素的视图的最佳方式是什么?
Given an element on the page — out of context of the view — what would be the best way to get the view for the element?
例如,假设某个事件影响页面上的一堆元素,我想在与受影响元素关联的每个视图上调用一个方法.
For example, say some event affects a bunch of elements on a page and I want to call a method on every view associated with the affected elements.
一种方法是将视图分配给元素的数据,但我想知道我是否错过了一些更聪明的东西:
One way would be to assign the view to the element's data, but I'm wondering if I've missed something smarter:
var myview = BackBone.View.extend({
initialize: function(options) {
$(this.el).data('view', this);
...
}
});
(我在 jQuery 1.5 中使用 Backbone.)
(I'm using Backbone with jQuery 1.5.)
推荐答案
我刚刚为此编写了一个 jQuery 插件.它还使用 .data()
方法.
I've just written a jQuery plugin for this. It also uses the .data()
method.
我已经包装/代理了 Backbone View setElement
方法以将所需的数据附加到视图的 $el
属性.
I have wrapped / proxied the Backbone View setElement
method to attach the required data to the view's $el
property.
注册是在幕后像这样完成的:
Registration is done behind the scenes like so:
$(myViewsEl).backboneView(myView);
检索:
插件向上遍历 DOM 层次结构(使用 .closest()
)直到找到具有所需数据条目的元素,即具有关联视图的 DOM 元素:
Retrieval:
The plugin traverses up the DOM hierarchy (using .closest()
) until it finds an element with the required data entry, i.e a DOM element with an associated view:
var nearestView = $(e.target).backboneView();
此外,我们可以指定我们希望获得什么类型的 Backbone View,继续向上层级直到找到匹配类型的实例:
In addition, we can specify what type of Backbone View we wish to obtain, continuing up the hierarchy until we find an instance of matching type:
var nearestButtonView = $(e.target).backboneView(ButtonView);
JSFiddle 示例:
可以在此处找到.
我希望我认为这里不涉及内存泄漏是正确的;如果 setElement
被第二次调用,则执行取消链接",并且由于删除视图的元素调用 .remove()
默认情况下,它也会破坏所有数据.如果您有不同的想法,请告诉我.
I hope I am correct in thinking there are no memory leaks involved here; An 'unlink' is performed if setElement
is called a second time round, and since removing a view's element calls .remove()
by default, which destroys all data as well. Let me know if you think differently.
(function($) {
// Proxy the original Backbone.View setElement method:
// See: http://backbonejs.org/#View-setElement
var backboneSetElementOriginal = Backbone.View.prototype.setElement;
Backbone.View.prototype.setElement = function(element) {
if (this.el != element) {
$(this.el).backboneView('unlink');
}
$(element).backboneView(this);
return backboneSetElementOriginal.apply(this, arguments);
};
// Create a custom selector to search for the presence of a 'backboneView' data entry:
// This avoids a dependency on a data selector plugin...
$.expr[':'].backboneView = function(element, intStackIndex, arrProperties, arrNodeStack) {
return $(element).data('backboneView') !== undefined;
};
// Plugin internal functions:
var registerViewToElement = function($el, view) {
$el.data('backboneView', view);
};
var getClosestViewFromElement = function($el, viewType) {
var ret = null;
viewType = viewType || Backbone.View;
while ($el.length) {
$el = $el.closest(':backboneView');
ret = $el.length ? $el.data('backboneView') : null;
if (ret instanceof viewType) {
break;
}
else {
$el = $el.parent();
}
}
return ret;
};
// Extra methods:
var methods = {
unlink: function($el) {
$el.removeData('backboneView');
}
};
// Plugin:
$.fn.backboneView = function() {
var ret = this;
var args = Array.prototype.slice.call(arguments, 0);
if ($.isFunction(methods[args[0]])) {
methods[args[0]](this);
}
else if (args[0] && args[0] instanceof Backbone.View) {
registerViewToElement(this.first(), args[0]);
}
else {
ret = getClosestViewFromElement(this.first(), args[0]);
}
return ret;
}
})(jQuery);
这篇关于Backbone.js - 给定一个元素,我如何获得视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!