Backbone 模型
来源:互联网 发布:家庭影院网络播放器 编辑:程序博客网 时间:2024/06/06 15:00
BackBone模型源码2013-06-06 11:12:01
首先是 Model 模块的源码:
模型的构造函数,用于创建各个模型。各个模型都会拥有唯一的 cid ,提供的 modelOptions 列表中的选项将直接连接到原型,其余 options 中的将使用 set 来处理,set是 Model 的核心操作。会触发模型"change"事件。具体属性的话可以在此了解, 拔了一张强大的图~
以下为 Model 模块的原型中的方法,其中的 set 为核心方法,是控制当有属性改变时触发改变对象的 change 事件。 下面为 Model模块的使用以及原型方法的源码。
首先我们在页面上画一个黑色的矩形,并且 id 为 side。 我们使用模型控制进行颜色更改。
虽然感觉过程有点绕,中间有了 Model 这一概念来对事件进行控制,但是这样很好的使我们将结构分离开,容易控制整体以及之后的变更都会变得异常简单。
接下来就是 Model 原型中的方法:
分类: JavaScript
Backbone 模型 - Backbone.Model
首先是 Model 模块的源码:
- // Backbone **Models** 在框架中是基础的数据对象 --
- // 常常代表你服务器中数据库表中的一行.
- // 为一个离散的数据块,和一堆对这些数据进行计算转换的有用的相关的方法
- // 使用指定的属性创建一个新的模型.
- // 会自动生成并分配一个用户id (`cid`),依赖与 Underscore 的几个方法
- var Model = Backbone.Model= function(attributes,options) {
- var defaults;
- var attrs = attributes || {};
- options ||(options = {});
- // Underscore 中生成id的方法
- this.cid= _.uniqueId('c');
- this.attributes= {};
- // 返回 options 中属性存在于 modelOptions 的一个对象
- _.extend(this, _.pick(options, modelOptions));
- if (options.parse) attrs= this.parse(attrs,options) || {};
- if (defaults= _.result(this,'defaults')){
- attrs = _.defaults({}, attrs, defaults);
- }
- this.set(attrs,options);
- this.changed= {};
- this.initialize.apply(this,arguments);
- };
模型的构造函数,用于创建各个模型。各个模型都会拥有唯一的 cid ,提供的 modelOptions 列表中的选项将直接连接到原型,其余 options 中的将使用 set 来处理,set是 Model 的核心操作。会触发模型"change"事件。具体属性的话可以在此了解, 拔了一张强大的图~
以下为 Model 模块的原型中的方法,其中的 set 为核心方法,是控制当有属性改变时触发改变对象的 change 事件。 下面为 Model模块的使用以及原型方法的源码。
首先我们在页面上画一个黑色的矩形,并且 id 为 side。 我们使用模型控制进行颜色更改。
- // 创建一个 有 changeColor 方法的模型,该方法会调用 set 更改 color 属性,set 会触发实例的 change:color 事件
- var Sidebar = Backbone.Model.extend({
- changeColor:function(){
- var cssColor = prompt("输入颜色");
- this.set({color:cssColor});
- }
- });
- // 建立一个模型的实例
- var side =new Sidebar();
- // 为该实例绑定 当属性 color 被 set (也就是触发change)后的事件
- side.bind("change:color",function(model,color){
- $(".side").css({background:color});
- alert("setted");
- });
- //然后我们运行 模型实例中的方法
- side.changeColor();
接下来就是 Model 原型中的方法:
点击(此处)折叠或打开
- _.extend(Model.prototype, Events,{
- // 当前与之前值有变化的 属性散列(哈希).
- changed: null,
- // 最后一次验证失败的返回值.
- validationError: null,
- // JSON 默认名称 `id` 属性名为 `"id"`. MongoDB 和
- // CouchDB 用户偏向于 `"_id"`.
- idAttribute: 'id',
- // 默认初始化空函数.
- // 用自己的逻辑初始化重写函数.
- initialize: function(){},
- // 返回一个模型的属性对象的拷贝.
- toJSON: function(options){
- return _.clone(this.attributes);
- },
- // 默认使用 `Backbone.sync` 代理
- // 如果需要可以自定义从写
- sync: function(){
- return Backbone.sync.apply(this,arguments);
- },
- // 获取属性值
- get: function(attr){
- return this.attributes[attr];
- },
- // 获取属性的 HTML-escaped 值.
- escape:function(attr){
- return _.escape(this.get(attr));
- },
- // 若属性值不为 null 或者 undefined 则返回 `true`
- // or undefined.
- has: function(attr){
- return this.get(attr)!= null;
- },
- // 在对象上建立模型的属性哈希, 触发 `"change"`.
- // 这是 模型 的核心操作, 更新数据, 通知那些需要知道 模型 状态变化的对象
- // backbone 野兽的心脏.
- set: function(key, val,options) {
- var attr, attrs, unset, changes, silent, changing, prev,current;
- if (key== null) returnthis;
- // 处理 `"key", value` 和 `{key: value}` 2种参数形式的情况.
- if (typeofkey ==='object') {
- attrs = key;
- options = val;
- } else{
- (attrs = {})[key]= val;
- }
- options || (options= {});
- // 执行验证.
- if (!this._validate(attrs,options))return false;
- // 提取 属性 和 可选项.
- unset = options.unset;
- silent = options.silent;
- changes = [];
- changing = this._changing;
- this._changing= true;
- if (!changing){
- this._previousAttributes= _.clone(this.attributes);
- this.changed= {};
- }
- current = this.attributes, prev= this._previousAttributes;
- // 检测 `id` 变化.
- if (this.idAttributein attrs) this.id= attrs[this.idAttribute];
- // 设置每一个属性, 更新或者删除当前值.
- for (attrin attrs) {
- val = attrs[attr];
- if (!_.isEqual(current[attr], val)) changes.push(attr);
- if (!_.isEqual(prev[attr], val)) {
- this.changed[attr]= val;
- } else{
- delete this.changed[attr];
- }
- unset ? delete current[attr]: current[attr]= val;
- }
- // 触发所用相应的属性改变.
- if (!silent){
- if (changes.length)this._pending= true;
- for (var i= 0, l = changes.length; i< l; i++){
- this.trigger('change:'+ changes[i],this, current[changes[i]],options);
- }
- }
- // while 循环 修改将被递归嵌套在'events'事件中
- if (changing)return this;
- if (!silent){
- while (this._pending){
- this._pending= false;
- this.trigger('change',this, options);
- }
- }
- this._pending= false;
- this._changing= false;
- return this;
- },
- // 从模型中移除一个属性, 触发 `"change"`.
- // `unset` 如果属性不存在设置为空
- unset: function(attr,options) {
- return this.set(attr,void 0, _.extend({},options, {unset: true}));
- },
- // 清楚模型中的所有属性,触发 `"change"`.
- clear:function(options){
- var attrs = {};
- for (varkey in this.attributes) attrs[key]= void 0;
- return this.set(attrs, _.extend({},options, {unset: true}));
- },
- // 确保 模型 在上一次更改后再一次更改 `"change"` event.
- // 如果指定了属性名称, 确定属性已经改变.
- hasChanged: function(attr){
- if (attr== null) return!_.isEmpty(this.changed);
- return _.has(this.changed, attr);
- },
- // 返回一个包含所有改变的属性的对象, 当没有属性被更改,就返回 false.
- // 常用来判断视图块是否需要更新或者那些属性需要保存到后端
- // 未设置的 属性将设置为 undefined.
- // 你也可以针对模型传递一个属性对象来改变,决定是否 *would be* 改变.
- changedAttributes: function(diff){
- if (!diff)return this.hasChanged()? _.clone(this.changed): false;
- var val, changed= false;
- var old = this._changing? this._previousAttributes: this.attributes;
- for (var attrin diff) {
- if (_.isEqual(old[attr],(val = diff[attr])))continue;
- (changed || (changed= {}))[attr]= val;
- }
- return changed;
- },
- // 获取一个属性之前,在最后一次 'change' 事件触发时候的值
- previous:function(attr){
- if (attr== null ||!this._previousAttributes)return null;
- return this._previousAttributes[attr];
- },
- // 获取上一次 `"change"` 事件时所有属性的值.
- previousAttributes: function(){
- return _.clone(this._previousAttributes);
- },
- // 从服务器端获取 模型 .
- // 如果服务器端的显示的模型与当前属性有区别,那么覆盖并且触发事件"change"`.
- fetch: function(options){
- options = options ? _.clone(options): {};
- if (options.parse===void 0) options.parse= true;
- var model = this;
- var success = options.success;
- options.success= function(resp){
- if (!model.set(model.parse(resp,options),options))return false;
- if (success) success(model, resp,options);
- model.trigger('sync', model, resp,options);
- };
- wrapError(this,options);
- return this.sync('read',this, options);
- },
- // 设置属性的哈希, 同步模型到服务器.
- // 如果服务器返回一个有区别的属性散列,那么模型的状态要重新设置
- save:function(key, val,options) {
- var attrs,method, xhr,attributes =this.attributes;
- // 处理 `"key", value` and `{key: value}` 2种参数情况.
- if (key== null ||typeof key === 'object') {
- attrs = key;
- options = val;
- } else{
- (attrs = {})[key]= val;
- }
- // 如果并不在等待队列中并且属性不存在, 保存行为以 `set(attr).save(null, opts)`格式.
- if (attrs&& (!options|| !options.wait)&& !this.set(attrs,options))return false;
- options = _.extend({validate:true},options);
- // 舍弃无效的模型 .
- if (!this._validate(attrs,options))return false;
- // 如果 `{wait: true}` 设置临时属性.
- if (attrs&& options.wait){
- this.attributes= _.extend({},attributes, attrs);
- }
- // 在服务器端保存成功后, 客户端可以与服务器端一起更新(可选)
- if (options.parse===void 0) options.parse= true;
- var model = this;
- var success = options.success;
- options.success= function(resp){
- // 确保属性在同步保存的时候可恢复.
- model.attributes= attributes;
- var serverAttrs = model.parse(resp,options);
- if (options.wait) serverAttrs= _.extend(attrs|| {}, serverAttrs);
- if (_.isObject(serverAttrs)&& !model.set(serverAttrs,options)){
- return false;
- }
- if (success) success(model, resp,options);
- model.trigger('sync', model, resp,options);
- };
- wrapError(this,options);
- method =this.isNew()? 'create' : (options.patch? 'patch' : 'update');
- if (method==='patch') options.attrs = attrs;
- xhr = this.sync(method,this, options);
- // 恢复属性.
- if (attrs&& options.wait)this.attributes= attributes;
- return xhr;
- },
- // 去除以及存在在服务器端的模型.
- // 如果集合中原有一个模型,那么去掉就好.
- // 如果 `wait: true` 传递过来, 在移除之前等待服务器响应.
- destroy: function(options){
- options = options ? _.clone(options): {};
- var model = this;
- var success = options.success;
- var destroy = function(){
- model.trigger('destroy', model, model.collection,options);
- };
- options.success= function(resp){
- if (options.wait|| model.isNew()) destroy();
- if (success) success(model, resp,options);
- if (!model.isNew()) model.trigger('sync', model, resp,options);
- };
- if (this.isNew()){
- options.success();
- return false;
- }
- wrapError(this,options);
- var xhr = this.sync('delete',this, options);
- if (!options.wait) destroy();
- return xhr;
- },
- // 模型在服务器端表示的默认的URL -- if you're
- // 如果你在使用 Backbone's 静态方法, 重写此方法来改变将被调用的端点.
- url:function(){
- var base = _.result(this,'urlRoot') || _.result(this.collection,'url') || urlError();
- if (this.isNew())return base;
- return base + (base.charAt(base.length- 1) === '/' ? '': '/')+ encodeURIComponent(this.id);
- },
- // **parse** 响应转换成模型上的哈希
- // 默认只是实现通过响应.
- parse:function(resp,options) {
- return resp;
- },
- // 创建一个新的 和当前模型有一样属性的模型.
- clone: function(){
- return newthis.constructor(this.attributes);
- },
- // 如果一个模型还没有存到服务器,那么他就是新的, 没有id.
- isNew: function(){
- return this.id== null;
- },
- // 检查模型当前是不是有效状态.
- isValid: function(options){
- return this._validate({}, _.extend(options|| {}, { validate: true }));
- },
- // 对下一个完全设置了模型属性的进行验证
- // 返回'true'. 否则触发 `"invalid"` 事件.
- _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;
- }
- });
0 0
- Backbone 模型
- backbone model模型
- Backbone模型整合React(React + Backbone Model)
- Backbone源码分析——MVC模型
- Backbone
- backbone
- backbone
- Backbone
- backbone
- backbone
- backbone
- Backbone
- Backbone
- Backbone
- backbone
- Phonegap-Android的backbone-min.js之模型
- #Backbone学习笔记(一)--模型(model)
- Phonegap-Android的backbone-min.js之视图与模型绑定
- Cookie,Session
- 布林带(BOLL)技术指标
- 微信小程序url参数传递
- SQL语句汇总(三)——聚合函数、分组、子查询及组合查询
- Python教程精华版(二)
- Backbone 模型
- JDBC复习
- houghline
- 《连载 | 物联网框架ServerSuperIO教程》- 18.集成OPC Client,及使用步骤。附:3.5 发布与更新说明。
- Centos7下查询java安装路径
- 基础——Linux命令学习
- lua环境搭建
- 【HDU4991】Ordered Subsequence(离散化+dp+树状数组)
- ServerSuperIO 3.5版本的体系结构,以及未来规划的几点思考