Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control. You extend Backbone.Model with your domain-specific methods, and Model provides a basic set of functionality for managing changes.
模型 是全部 Javascript 應用程序的核心,包括交互數據及相關的大量邏輯: 轉換、驗證、計算屬性和訪問控制。css
你能夠用特定的方法擴展 Backbone.Model , 模型 也提供了一組基本的管理變化的功能,這個東西就像是後端開發中的數據庫映射那個model同樣,也是數據對象的模型,而且應該是和後端的model有相同的屬性(僅是須要經過前端來操做的屬性)。html
簡而言之,就是圍繞着數據處理,如建立、校驗、銷燬和保存到服務端等等...前端
以前說了,模型能夠圍繞數據處理相似curd的操做,因此backbone就爲咱們提供了這樣的一個基礎模板,Backbone中的模型類是Backbone.Model,它包含了數據存儲,數據驗證,以及數據發生變更時觸發相關動做,咱們只要繼承就能使用這些特性了數據庫
用別人的框架,就須要瞭解別人的規則,這種學習成本是跑不掉的 - -後端
官方的demo服務器
下面是一個示例,它演示了定義一個模型使用一個自定義的方法,設置一個屬性,觸發一個事件的特定屬性的變化app
var Sidebar = Backbone.Model.extend({ promptColor: function() { var cssColor = prompt("Please enter a CSS color:"); this.set({color: cssColor}); } }); window.sidebar = new Sidebar; sidebar.on('change:color', function(model, color) { console.log('修改顏色',color) }); sidebar.set({color: 'white'}); sidebar.promptColor();
當models中值被改變時自動觸發一個"change"事件、全部用於展現models數據的views都會偵聽到這個事件,而後進行從新渲染。框架
Backbone.Model 是Backbone提供模板類,經過繼承extend構造本身Sidebar模型類dom
因此具備了on ,set 等等這種基礎的屬性與方法ide
那麼我看看backbone模型類模板能爲咱們提供什麼基礎功能
就是把模板類的方法繼承給子類,因此咱們子類都具備相同的特性了
Backbone.Model.extend
Backbone.Collection.extend
Backbone.Router.extend
Backbone.View.extend
擴充的靜態方法
Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
關於這個繼承很好理解,js的繼承經常使用的就是這個了
代碼簡單分析下
建立子類的載體,換句話就是咱們構造出來的那個新的類的一個新的構造器
if (protoProps && _.has(protoProps, 'constructor')) { child = protoProps.constructor; } else { child = function () { return parent.apply(this, arguments); }; }
若是用戶自定義了constructor函數,就用這個,不然就內部自行構建
以後就是複製靜態屬性到新的child
而後把父類的原型鏈的引用給指向child
這個請參考http://www.cnblogs.com/aaronjs/archive/2012/08/26/2657103.html
擴展了屬性,在constructor中擴展了__super__ 指向父類,繼承了模板的原型鏈上的方法
能夠想像下模型實例用來存儲數據表中的一行數據(row)
Backbone利用model的attributes與數據庫的字段一一對應
使用set和get方法來設置或獲取模型的屬性。
var Model = Backbone.Model = function (attributes, options) { var attrs = attributes || {}; options || (options = {}); this.cid = _.uniqueId('c');this.attributes
= {}; if (options.collection) this.collection = options.collection; if (options.parse) attrs = this.parse(attrs, options) || {}; attrs = _.defaults({}, attrs, _.result(this, 'defaults')); this.set(attrs, options); this.changed = {}; this.initialize.apply(this, arguments); };
不能把屬性直接寫到 Backbone.Model.extend的擴展中,緣由也很簡單,一個是封裝性,最重要的原型上是共享的,若是是引用類型就糟糕了
因此屬性在模型實例上有一個專門的屬性來存儲:this.attributes,set/get都圍繞this.attributes操做。
Models 用來建立數據,校驗數據,存儲數據到服務器端.Models 還能夠綁定事件。好比用戶動做變化觸發 models 的 change 事件,全部展現此model 數據的 views 都會接收到 這個 change 事件,進行重繪。
若是任何屬性的改變模型的狀態,「改變」事件將觸發模式
只是實現了一個自定義事件功能
監聽屬性color的改變
sidebar.on('change:color', function(model, color) { console.log('修改顏色',color) });
設置改變
sidebar.set({color: 'white'});
源碼實現
Backbone.Model繼承了自定義事件Events
_.extend(Model.prototype, Events, {});
sidebar實例繼承了Backbone.Model.
var Sidebar = Backbone.Model.extend
因此Sidebar也具備自定義事件的功能,只是在set方法裏面按照規則觸發
使用 set()
方法建立或者設置屬性值能夠觸發自定義事件,
if (!silent) { if (changes.length) this._pending = options; for (var i = 0, l = changes.length; i < l; i++) { this.trigger('change:' + changes[i], this, current[changes[i]], options); } }
PS:
咱們知道雖然屬性是存儲this.attributes中,可是若是是直接
實例.attributes.name = "屬性名";
這樣很明顯就丟失了自定義事件了,因此使用 set()
是改變模型狀態並觸發其變動事件的惟一方法
Model 這一律念來對事件進行控制,可是這樣很好的使咱們將結構分離開,容易控制總體以及以後的變動都會變得異常簡單。
驗證模型數據規範
var Chapter = Backbone.Model.extend({ validate: function(attrs, options) { if (attrs.end < attrs.start) { return "can't end before it starts"; } } });
源碼部分
_validate: function (attrs, options) { if (!options.validate || !this.validate) return true; attrs = _.extend({}, this.attributes, attrs); var error = this.validationError = this.validate(attrs, options) || null; if (!error) return true; this.trigger('invalid', this, error, _.extend(options, {validationError: error})); return false; }
執行了this.validate(attrs, options) 自定義驗證函數,可見若是返回了true
就會執行this.trigger('invalid', this, error, _.extend(options, {validationError: error})); 錯誤通知了
餘下的fetch,save,sync,url等等放在合集中在講吧