Backbone:为什么要将 `$('#footer')` 分配给 `el`?

Backbone: Why assign `$('#footer')` to `el`?

我发现了以下语句:

el: '#footer'

var todosView = new TodosView({el: $('#footer')});

为什么要将$('#footer')分配给el?这才是真正让我困惑的地方。我看了这里的post,What is the difference between $el and el in Backbone.js views?,还是一头雾水。

另外,我读到: view.$el 属性 等价于 $(view.el)view.$(selector) 等价于 $(view.el).find(selector)。在我们的 TodoView 示例的渲染方法中,我们看到 this.$el 用于设置元素的 HTML 和 this.$() 用于查找 class 'edit' 的子元素。

但是,有人说 If you call $(this.el), your just keep executing the jquery selector to get the same jquery object. '$el' is the cached version of $(this.el)

什么是 "cached version"?

$elel有什么区别?

el view property

this.el can be resolved from a DOM selector string or an Element; otherwise it will be created from the view's tagName, className, id and attributes properties. If none are set, this.el is an empty div, which is often just fine.

它是一个 DOM 元素对象引用。 不要直接设置el,如果要更改,请改用view.setElement method

$el property

A cached jQuery object for the view's element. A handy reference instead of re-wrapping the DOM element all the time.

我喜欢用户 mu is too short puts it:

this.$el = $(this.el);

另外不要直接设置$el使用view.setElement method.

el 选项

An el reference may also be passed in to the view's constructor.

new Backbone.View({ el: '#element' });
new Backbone.View({ el: $('#element') }); // unecessary

它覆盖 el 属性,然后用于 $el 属性。

如果传递了选择器字符串,它将被替换为它所代表的 DOM 元素。

为什么要将 $('#footer') 赋值给 el?

this.el 可以是 jQuery 对象。你可以看到 Backbone 确保 el 是一个 DOM 元素并且 $el 是它在 _setElement function 中的一个 jQuery 对象:

_setElement: function(el) {
  this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
  this.el = this.$el[0];
},

这说明了为什么 this.$el 等同于 $(this.el)

但是Backbone.$是什么?

Backbone 保留对 $.

的引用

For Backbone’s purposes, jQuery, Zepto, Ender, or My Library (kidding) owns the $ variable.

在我们的例子中,$ 是 jQuery,所以 Backbone.$ 只是 jQuery,但是 Backbone 依赖关系是灵活的:

Backbone's only hard dependency is Underscore.js ( >= 1.8.3). For RESTful persistence and DOM manipulation with Backbone.View, include jQuery ( >= 1.11.0), and json2.js for older Internet Explorer support. (Mimics of the Underscore and jQuery APIs, such as Lodash and Zepto, will also tend to work, with varying degrees of compatibility.)

this.$(selector) 等同于 $(view.el).find(selector)

其实效率高一点$ view function就是:

$: function(selector) {
  return this.$el.find(selector);
},

什么是缓存的 jQuery 对象?

在这种情况下,它仅意味着一个 jQuery 对象保存在一个变量中,该变量在视图中被重用。它避免了每次查找带有 $(selector) 的元素的昂贵操作。

您可以(并且应该)尽可能使用这个小优化,比如在 render 函数中:

render: function() {
    this.$el.html(this.template(/* ...snip... */));
    // this is caching a jQuery object
    this.$myCachedObject = this.$('.selector');
},

onExampleEvent: function(e) {
    // avoids $('.selector') here and on any sub-sequent example events.
    this.$myCachedObject.toggleClass('example');
}

在 jQuery 缓存对象变量前加上 $ 只是一个标准,不是必需的。


Backbone的源代码不到2000行,文档齐全,易于阅读。我非常鼓励大家深入研究它以轻松理解底层逻辑。

他们还提供了一个更容易阅读的 annotated source page

补充阅读