backbone 学习之View
View,包含两部分的职责View和Controller.当model更改的时候 view也会相应的跟着更改,同理view更改的时候model也更改,有点MVVM的感觉
直接看源码:
// Backbone.View // ------------- // Backbone Views are almost more convention than they are actual code. A View // is simply a JavaScript object that represents a logical chunk of UI in the // DOM. This might be a single item, an entire list, a sidebar or panel, or // even the surrounding frame which wraps your whole app. Defining a chunk of // UI as a **View** allows you to define your DOM events declaratively, without // having to worry about render order ... and makes it easy for the view to // react to specific changes in the state of your models. // Creating a Backbone.View creates its initial element outside of the DOM, // if an existing element is not provided... var View = Backbone.View = function(options) { this.cid = _.uniqueId('view'); this._configure(options || {}); this._ensureElement(); // 确保el this.initialize.apply(this, arguments); this.delegateEvents(); // 绑定事件 }; // Cached regex to split keys for `delegate`. var delegateEventSplitter = /^(\S+)\s*(.*)$/; // List of view options to be merged as properties. // view中的关键属性 var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events']; // Set up all inheritable **Backbone.View** properties and methods. _.extend(View.prototype, Events, { // The default `tagName` of a View's element is `"div"`. // view 的tagName 在没有设置el的时候,默认view的内容的容器就是div tagName: 'div', // jQuery delegate for element lookup, scoped to DOM elements within the // current view. This should be prefered to global lookups where possible. // 查找元素 $: function(selector) { return this.$el.find(selector); }, // Initialize is an empty function by default. Override it with your own // initialization logic. initialize: function(){}, // **render** is the core function that your view should override, in order // to populate its element (`this.el`), with the appropriate HTML. The // convention is for **render** to always return `this`. // 渲染函数 一般需要重写 render: function() { return this; }, // Remove this view by taking the element out of the DOM, and removing any // applicable Backbone.Events listeners. // 移除元素 remove: function() { this.$el.remove(); this.stopListening(); return this; }, // Change the view's element (`this.el` property), including event // re-delegation. // 设置元素 setElement: function(element, delegate) { if (this.$el) this.undelegateEvents(); // 解绑 释放内存 this.$el = element instanceof Backbone.$ ? element : Backbone.$(element); this.el = this.$el[0]; if (delegate !== false) this.delegateEvents(); return this; }, // Set callbacks, where `this.events` is a hash of // // *{"event selector": "callback"}* // // { // 'mousedown .title': 'edit', // 'click .button': 'save' // 'click .open': function(e) { ... } // } // // pairs. Callbacks will be bound to the view, with `this` set properly. // Uses event delegation for efficiency. // Omitting the selector binds the event to `this.el`. // This only works for delegate-able events: not `focus`, `blur`, and // not `change`, `submit`, and `reset` in Internet Explorer. // 根据键值对来绑定事件 delegateEvents: function(events) { if (!(events || (events = _.result(this, 'events')))) return this; this.undelegateEvents(); for (var key in events) { var method = events[key]; if (!_.isFunction(method)) method = this[events[key]]; if (!method) continue; var match = key.match(delegateEventSplitter); var eventName = match[1], selector = match[2]; method = _.bind(method, this); eventName += '.delegateEvents' + this.cid; if (selector === '') { this.$el.on(eventName, method); } else { this.$el.on(eventName, selector, method); } } return this; }, // Clears all callbacks previously bound to the view with `delegateEvents`. // You usually don't need to use this, but may wish to if you have multiple // Backbone views attached to the same DOM element. // 解绑事件 undelegateEvents: function() { this.$el.off('.delegateEvents' + this.cid); return this; }, // Performs the initial configuration of a View with a set of options. // Keys with special meaning *(e.g. model, collection, id, className)* are // attached directly to the view. See `viewOptions` for an exhaustive // list. // 配置options中的viewOptions中的项到this上 _configure: function(options) { if (this.options) options = _.extend({}, _.result(this, 'options'), options); _.extend(this, _.pick(options, viewOptions)); // 拓展this this.options = options; }, // 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. // 确保有el $el _ensureElement: function() { if (!this.el) { var attrs = _.extend({}, _.result(this, 'attributes')); // options中的attributes if (this.id) attrs.id = _.result(this, 'id'); // id if (this.className) attrs['class'] = _.result(this, 'className'); var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs); this.setElement($el, false); } else { this.setElement(_.result(this, 'el'), false); } } });
欢迎指导、纠错、建议。