首页 >

简单了解Backbone.js的Model模型以及View视图的源码

web前端|js教程简单了解Backbone.js的Model模型以及View视图的源码
Backbone,Model,View,JavaScript
web前端-js教程
Backbone.Model
周边一卡通源码,安装js提示vscode,没有内存ubuntu,Tomcat密码爆破,帆软内置sqlite3,个人信息泄露是爬虫软件吗,php 服务器监控,外包seo推广哪里好,psd 3d模板免费下载网站,互联网金融网站模板lzw
今天我们先来谈谈Backbone.js MVC 中的 M , Model是backbone的核心部分,包含着页面展示内容的数据,还有围绕着数据操作的各种 转换,校验,计算 ,权限控制,服务端交互等等操作,你可以通过 Backbone.Model.extend() 生成你的model , 当然生成的model也可以作为一个基类去向下扩展更多的model
会员卡源码,ubuntu文件目录共享,为啥tomcat会闪退,爬虫拍摄视频,php取地址符,嘉善一站式seo推广哪家好lzw
 var People = Backbone.Model.extend({      }); var Man = People.extend({ });
Backbone.Model Api
帝国源码搭建手机版,mdk3 ubuntu,tomcat图片会自动删除吗,爬虫逆向学习,php和c语言的区别,zero 访谈seolzw
Backbone.Model 提供了大量方法用于实现一个Model的基本操作,当然其中最基本的还是基于 Backbone.Events 的事件机制,在Model的attributes发生变化的时候,相应的 change:attr事件会被触发,下面是提供的API:

其中有对数据进行服务端操作的方法:

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:

方法不多,下面对部分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.$('').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中大部分的逻辑都是开发者自己去扩展的。


简单了解Backbone.js的Model模型以及View视图的源码
  • JavaScript的Backbone.js框架环境搭建及Hellow world示例
  • JavaScript的Backbone.js框架环境搭建及Hellow world示例 | JavaScript的Backbone.js框架环境搭建及Hellow world示例 ...

    简单了解Backbone.js的Model模型以及View视图的源码
  • 目前流行的前端框架有哪些?
  • 目前流行的前端框架有哪些? | 目前流行的前端框架有哪些? ...

    简单了解Backbone.js的Model模型以及View视图的源码
  • Backbone.js的一些使用技巧_javascript类库
  • Backbone.js的一些使用技巧_javascript类库 | Backbone.js的一些使用技巧_javascript类库 ...