麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > JavaScript > 正文

簡單了解Backbone.js的Model模型以及View視圖的源碼

2019-11-20 10:36:04
字體:
來源:轉載
供稿:網友

Backbone.Model

今天我們先來談談Backbone.js MVC 中的 M , Model是backbone的核心部分,包含著頁面展示內容的數據,還有圍繞著數據操作的各種 轉換,校驗,計算 ,權限控制,服務端交互等等操作,你可以通過 Backbone.Model.extend() 生成你的model , 當然生成的model也可以作為一個基類去向下擴展更多的model

 var People = Backbone.Model.extend({      }); var Man = People.extend({ });

Backbone.Model Api

Backbone.Model 提供了大量方法用于實現一個Model的基本操作,當然其中最基本的還是基于 Backbone.Events 的事件機制,在Model的attributes發生變化的時候,相應的 change:attr事件會被觸發,下面是提供的API:

2016214171632823.png (207×574)

其中有對數據進行服務端操作的方法:

  • sync : 包裝了Backbone.sync,xhr的基類
  • fetch : 用于從服務端獲取數據
  • save : 向服務端持久化數據
  • destroy: 從服務端刪除數據

model中數據操作的方法:

  • get : 從attributes中獲取數據
  • set : 向attributes中設置數據
  • escape : 對數據進行編碼 ,使用的是underscore的 _.escape
  • has : attributes中有無對應數據
  • unset : 從attributes中刪除數據
  • clear : 清空attributes數據
  • changed : 與上個狀態(執行過set,unset),相比變化的值
  • toJSON : 將 attributes 序列化成一個對象
  • parse : 當設置項parse為真的時候,初始化/set/unset/fetch等數據操作中會對目標數據進行一個解析返回解析后的對象,此方法為空方法,需要重寫覆蓋
  • hasChanged : 與上個狀態(執行過set,unset),相比是否發生過變化
  • changeAttributes : 與上個狀態(執行過set,unset),相比發生的所有值
  • previous : 前一狀態 (執行過set,unset),該屬性對應的值
  • previousAttributes : 與上個狀態(執行過set,unset),發生過變化對象的前一個狀態的所有值

model中數據校驗的方法:

  • validate:用于對model中數據進行校驗,需要重寫覆蓋默認方法
  • validationError : 返回最近一個invalid時返回的值
  • isValid : 調用_validate方法

下面會針對一些重點的api進行講解:

構造函數

  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);   };

構造函數主要對初始化的數據和選項進行設置,然后會對生成一個唯一的cid用于標示model,如果options中的parse為true,那么會對初始化數值通過parse方法進行一個解析,調用set方法,所有的初始值會被存入attributes中,調用initialize初始化方法 。model的初始化就完成了。

set

model.set(attributes, [options])

set方法會將值設置進入attribute中,設置時如果設置了slient為true,會觸發相應的 change:attr 的事件,最后統一觸發change事件,set方法部分代碼如下:

 

  set: function(key, val, options) {     //......      // key值可以是鍵值對,也可以是一個字符串,將賦值傳入attrs屬性中      if (typeof key === 'object') {     attrs = key;     options = val;    } else {     (attrs = {})[key] = val;    }   // ....    //對設置的值進行校驗       if (!this._validate(attrs, options)) return false;    unset = options.unset; // unset為true時會刪除設置的值,unset方法就是通過 set(key,val,{unset:true})去實現的       //當對象正在被被設置的時候,不給 previousAttributes 賦值    if (!changing) {     this._previousAttributes = _.clone(this.attributes);     this.changed = {};    }     current = this.attributes, prev = this._previousAttributes;     //如果對Id進行了設置,則對對象的id屬性也進行改變    if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];     //進行 設置或者是刪除操作    for (attr in attrs) {     val = attrs[attr];     if (!_.isEqual(current[attr], val)) changes.push(attr);     if (!_.isEqual(prev[attr], val)) {      this.changed[attr] = val;//為model的changed進行設置     } else {      delete this.changed[attr];     }     unset ? delete current[attr] : current[attr] = val;//如果unset被設置成true了,則進行刪除操作    }     //在silent不為false 的情況下,進行change:attr事件發送    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);     }    }     //觸發change事件    if (changing) return this;    if (!silent) {     while (this._pending) {      options = this._pending;      this._pending = false;      this.trigger('change', this, options);     }    }    this._pending = false;    this._changing = false;    return this;     }

set的整個流程就是 對傳入的數值進行處理,變成一個鍵值對,然后對數值進行校驗,檢查正確性,然后開始進行設置操作,設置時檢查數值時候是發生改變的,如果有則加入一個 changeed的對象中,然后檢查unset的值,進行相應的添加更新刪除操作。然后依次觸發change:attr和change事件。

save

model.save([attributes], [options])

save方法用于向客戶端持久化數據,會根據數據的不同和配置的不同選擇使用create,update或者是patch,并且觸發 sync 事件,以下為部分代碼:

  save: function(key, val, options) {         // ......      //當設置了wait屬性true的時候 , save方法先不執行set方法(不觸發change事件),只執行validate    if (attrs && !options.wait) {     if (!this.set(attrs, options)) return false;    } else {     if (!this._validate(attrs, options)) return false;    }    //如果wait為true,設置this.attributes    if (attrs && options.wait) {     this.attributes = _.extend({}, attributes, attrs);    }     // .....       var model = this;    var success = options.success;    options.success = function(resp) {     // Ensure attributes are restored during synchronous saves.     model.attributes = attributes;     var serverAttrs = model.parse(resp, options);     //如果wait為true , 那么會在請求返回之后才進行set操作     if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);     if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {      return false;     }     if (success) success(model, resp, options);     //觸發 sync 事件     model.trigger('sync', model, resp, options);    };    //生成XHR onerror 回調函數    wrapError(this, options);    //選擇方法    method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');    if (method === 'patch') options.attrs = attrs;    xhr = this.sync(method, this, options);     // Restore attributes.    if (attrs && options.wait) this.attributes = attributes;    //返回xhr對象    return xhr;  }

 
save 中最需要注意的就是 wait 的設置,當wait為真的時候,save返回會在xhr返回之后再執行set操作,而不是在xhr之前就進行set操作,因此change事件的觸發時機也就不同了。

之前說過整個Backbone都是通過事件串聯起來的,所以對于事件觸發時機的了解和把握是非常重要的,不然會在開發過程中導致一些奇怪的問題出現。

Backbone.View
前面已經對backbone中的Event、Model、Collection代碼進行了分析,現在我們來看下MVC中的V部分,也就是Backbone.View,View在Backbone中主要用于溝通頁面中的DOM和Backbone.Model/Collection,頁面的邏輯操作,DOM事件的綁定等,View部分的代碼非常簡答,加上注釋只有110左右。 View部分有一下API:

2016214171843674.png (197×245)

方法不多,下面對部分API進行介紹:

構造方法

  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events']; var View = Backbone.View = function(options) {   this.cid = _.uniqueId('view');   options || (options = {});   _.extend(this, _.pick(options, viewOptions));   this._ensureElement();   this.initialize.apply(this, arguments);   this.delegateEvents(); };

構造方法中為View生成了一個唯一的cid,以'view'開頭,然后進行對目標屬性viewOptions進行合并,接著調用_ensureElement判斷el的情況,接著調用delegateEvents進行方法綁定,初始化完成 。

delegateEvents

view.setElement(element)   setElement: function(element, delegate) {    if (this.$el) this.undelegateEvents();//如果已經存在this.$el,進行事件解綁    //對$el進行賦值,本質是一個jquery或者是 Lo-Dash and Zepto 對象    this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);    //把dom element 賦值給el    this.el = this.$el[0];     //如果沒有顯式傳值,則進行事件綁定    if (delegate !== false) this.delegateEvents();    return this;   }

setElement方法用于設置View對應的element , 這個方法在new的時候會被調用, 如果想要在使用過程中改變View的dom元素指向,可調用這個方法進行重新設置

_ensureElement

  _ensureElement: function() {     //如果已經對el進行設置,直接調用setElement方法    if (!this.el) {//如果沒有設置,生成一個元素對象,再調用setElement方法     var attrs = _.extend({}, _.result(this, 'attributes'));     if (this.id) attrs.id = _.result(this, '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);    }  }

_ensureElement這個方法是內部方法,在構造函數中使用,用于判斷指定的el在頁面中存不存在,如果存在則對$el進行賦值,如果不存在,則生成一個$el,但是要注意這個對象是沒有落地到dom樹中的 。

delegateEvents

delegateEvents([events])    // *{"event selector": "callback"}*   //   //   {   //    'mousedown .title': 'edit',   //    'click .button':   'save',   //    'click .open':    function(e) { ... }   //   }   delegateEvents: function(events) {      //如果不存在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' + cid 組成,       //這么做能夠在undelegateEvents的時候選擇到這個View的所有事件       eventName += '.delegateEvents' + this.cid;       if (selector === '') {        this.$el.on(eventName, method);       } else {        this.$el.on(eventName, selector, method);       }      }      return this;   }

在View中你可以使用一個 key:value 集合指定對應的事件,在初始化的時候構造函數會調用delegateEvents進行綁定,需要注意的是所有在key中指定的元素的父元素都必須是$el,也就是說元素必須是$el的子節點,否則綁定失敗。

View和其他backbone模塊一個區別就是沒有自己的內建自定義事件,當然他也組合了Events模塊,但是所有的事件都需要自己進行建立。View主要是一個MVC模型的承載,其實真正的功能不多,其實從模型層面上看V在前端開發中是最接近業務邏輯的,所以在View中大部分的邏輯都是開發者自己去擴展的。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 激情毛片 | 国产精品久久久久久久av三级 | 免费视频一区 | 最新中文在线视频 | 成人电影毛片 | 中文字幕亚洲一区二区三区 | 亚洲免费观看视频 | 九九视屏| 97人人草| 中文字幕伦乱 | 性大片免费看 | 久色视频网站 | 亚洲嫩草av | 日韩在线欧美在线 | 少妇一级淫片高潮流水电影 | 欧美一级黄色片在线观看 | 国产成人精品一区二区仙踪林 | 99pron| 孕妇体内谢精满日本电影 | 国产99久久久国产精品下药 | 一区二区久久电影 | 老a影视网站在线观看免费 国产精品久久久久久久久久尿 | 黄色网欧美 | 国产91一区二区三区 | 久久久一区二区三区精品 | 欧美一级片 在线播放 | 久久精品亚洲一区二区三区观看模式 | 国产午夜精品一区二区三区四区 | 久久最新网址 | 久久亚洲精品国产一区 | www国产成人免费观看视频 | 久久www视频 | 日韩精品久久久 | 美国一级毛片片aa久久综合 | 国产一级淫片免费看 | 成人性生活视频 | 久久99国产综合精品 | 成年人黄色免费电影 | 亚洲国产网站 | 国产一区二区精品免费 | 日本一区二区在线看 |