现在进入最关键的组件 - 模型。模型用来存储应用的所有数据,以及直接和数据操作相关的逻辑。Backbone中的模型类是Backbone.Model,它包含了数据存储,数据验证,以及数据发生变动时触发相关动作。
一般可以把模型与后端绑定(ORM),模型改变的同时向后端发起请求(Ajax)更新数据(数据库)。也有把模型和DOM元素绑定,模型改变时更新HTML界面。
一、模型
可以直接new一个Backbone.Model,它返回一个Model
var model = new Backbone.Model() model.set({name: 'Backus', age: 35})
也可扩展Backbone.Model,定义自己的模型类(构造器)
var Person = Backbone.Model.extend({ initialize: function(name, age) { this.set({name: name, age: age}) } })
extend的第一个参数为一个对象,它将成为模型实例的属性。第二个参数将成为类属性(类静态属性、方法)。这在 Backbone的写类方式 有所提及。
二、模型与属性 - set/get
使用set和get方法来设置或获取模型的属性。属性在模型实例上有一个专门的属性来存储:this.attributes,set/get都围绕this.attributes操作。
设置模型Person的属性
var p1 = new Person() p1.set({name: 'Backus', age: 87})
Firefox控制台使用get方法获取属性
set方法除了可以接受对象形式参数,也可以接受前两个key,value方式
set方法内部对此做了兼容,第一个参数key如果是对象类型,直接将该对象拷贝到this.attributes上,如果key是字符串,那么将在内部把key,value转成一个临时对象attrs再拷贝到this.attributes上。
set还有第三个可选参数options,如果设置了options.validate=true,且模型如果定义了validate方法,那么每次设置时将调用该方法进行校验,校验未通过将不进行后续设置,而直接返回。
var Person = Backbone.Model.extend({ validate: function(attrs) { if ( !_.isString(attrs.name) ) return 'name 必须是字符串类型' if ( !_.isNumber(attrs.age) ) return 'age 必须是数字类型' } }) var p1 = new Person() p1.on('invalid', function(model, error, agr) { console.log(error) }) p1.set({name: 'Backus', age: 87})
从控制台输入如下
可以看到输出了提示信息“name 必须是字符串类型”,再打印出p1的JSON格式
可以看到name仍然是“Backus”,并未修改。
在set方法内部会调用私有的this._validate方法,该方法如下
_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; }
1.0与之前版本实现不同,必须显示的设置options.validate=true,且模型必须实现this.validate方法,才会进行验证,否则直接返回true。1.0之前默认就进行验证,无需设置options.validate为true。验证无效(失败)后会派发“invalid”事件,因此可以监听该事件做后续处理,比如显示一些必要的提示信息。
默认情况下,set调用都会触发“change”事件,如下
p1.on('change', function(model, error) { console.log('attributes has changed') }) p1.set({name: 'Backus', age: 87})
你可以在回调函数中去更新视图或处理特定的业务逻辑。如果你显示设置第三个参数中silent为true,将不会触发“change”事件。
p1.set({name: 'Backus', age: 87}, {silent: true})
从set源码可以看到,this._validate执行在前,this.trigger在后。也就是说如果验证失败,那么就不会执行change事件。
附set方法执行流程图
三、把模型保存到服务器 - save
save方法会把模型保存到服务器端,它的参数和set完全一致。内部调用set和sync方法。
以下几点需要注意
1. 默认会进行属性校验,即options.validate为true,校验失败将不会请求后台程序,也不会设置模型的this.attributes,直接返回,见源码
if (attrs && !options.wait) { if (!this.set(attrs, options)) return false; } else { if (!this._validate(attrs, options)) return false; }
2. 首次保存时(isNew),会采用create方式(HTTP post),已存在的model则只需要update方式(HTTP put)
如下
var p1 = new Person() p1.save({name: 'Backus', age: 87}) // create p1.save({name: 'John'}) // update
3. 可以传success和error两个回调函数以处理保存成功与失败场景
var p1 = new Person() p1.save({name: 'Backus', age: 87}, { success: function() {}, error: function() {} })
4. 事件,save成功后会依次触发模型的“change”、“request”、“sync”事件。如果监听了这些事件,那么回调将得到执行
四、从服务器获取模型 - fetch
从服务器端获取使用fetch方法,fetch方法很短
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); },
1. 它使用read方式(HTTP get)
2. 请求成功后调用set方法设置模型属性(this.attributes),设置失败则直接返回不调用success,设置成功接着调用success,最后派发“sync”事件
五、模型的事件 - change/invalid/sync
上面已经提到的事件 change、 invalid、sync。change事件还可以只监听指定的属性,格式:"change:" + attributeName。如下
var p1 = new Person() p1.on('change:name', function(model, error) { console.log('name has changed') })
控制台中分别设置下name和age
可以看到,只有设置name时才触发事件。
除了Backbone.Model自身提供的事件,你还可以给自己的Model添加自定义的事件以满足需求。
六、鸟瞰图
1. 内部状态,各属性影响的方法
2. 构造器执行流程
pp
相关推荐
用于 Backbone 模型的简约轻量级模式验证器。 受到松散启发。 随意分叉、修改并满足您的需求。 欢迎请求请求和问题。 npm install backbone-schema 用法 可以在浏览器或服务器中使用。 只需在您的项目中包含主干...
主干.hashmodels 将多个 Backbone 模型连接到 url 哈希概述在大型单页 Web 应用程序中,您通常会有多个 UI 小部件来调整页面内容(过滤可见项目、更改排序顺序、设置颜色首选项、选择项目等)。如果您想保存和恢复...
一个 Backbone 插件,用于缓存获取 Backbone 模型和集合的结果。 主要用例:如果您很少更改应用程序不同部分所需的集合或模型集,则只能获取一次。 Caching-fetcher 使您无需检查集合中的任何项目是否已获取。 ...
骨干角色 Backbone.Rel通过轻量级的关系管理器扩展了Backbone模型。它是如何工作的? 原料药相对Backbone.Rel公开了一个关系getter的方法rel 。有很多您可以在Model实现hasMany方法来定义关系。 该方法必须返回一个...
后解析backparse是commonjs的实现,它将解析集成添加到了Backbone模型和集合中。 大量代码是从neebz的借用的。用法 // Load the `backparse` module instead of `backbone`. Pass in `appId`,// `apiKey` and `api...
例子。烂番茄骨干如何使用Rotten Tomatoes API填充Backbone模型的示例
主干本地化文本 在 Backbone 模型中具有本地化字段的简单方法 ##演示 您可以在试用
arcface backbone模型文件
用于将主干模型/集合与XMPP Pub-Sub节点同步的备用存储层 介绍 ,可以轻松地为其默认的RESTful JSON请求支持替代存储层。 该包通过将Backbone.Collection实例映射到Pub-Sub节点,并将它们的Backbone.Model实例映射到...
Backbone提供了可观察的模型,但是Human Model通过强制您明确定义模型将要存储的内容而使这一步骤更进一步,从而使模型代码最终可以自我记录,因为您现在可以简单地查看模型代码并看看他们应该存储什么。...
#Backbone 模型集合示例一个简单的示例应用程序,显示了 Backbone 模型和集合之间的关系。
骨干现场模型和收藏 这两个 Backbone mixin 旨在使 Pusher 的工作更加轻松。 它通过从服务器捕获 Pusher 事件来使您的模型和集合始终保持最新状态。 它还遵循“约定优于配置”的思想,并规定了应该与 Pusher 事件...
骨干合并 扩展 Backbone 的视图以允许在模型被放置到服务器时进行客户端冲突管理。
完整模型IntactModel 在很大程度上受到 Henrik Joreteg 的 HumanModel 的,如果不是迫切需要遗留支持(我在看着你... var Model = new Backbone . IntactModel ( { properties : { 'foo' : { type : 'string' } }} ) ;v
骨干蓝图 基于 JSON 模式创建模型/集合层次结构。 基于 JSON-Schema 规范,但在处理关系等方面略有修改。例子 var addressSchema = exports . addressSchema = { id : '/schemas/address' , title : 'Address' , ...
这个怎么运作首先创建一个Backbone模型定义,就像普通的Backbone应用程序一样。 var MyModel = Backbone . Model . extend ( {// Explicitly listing what attributes to expect in this modeldefaults : {name : ''...
你好React骨干 一个简单的Hello World例子,用用... 组件状态通过Backbone模型和主干React组件mixin设置,并在render方法中使用,当React创建/更新该组件时将调用该状态。 指示 安装 运行npm start以使应用程序在Web
Backbone.ModelBinding 项目状态:已放弃 我正式放弃这个项目。 在故意忽略不断增长的问题列表数月... 这个插件提供了一个简单的、基于约定的机制来在你的 Backbone 模型和你的 HTML 元素之间创建双向绑定,包括表单输
本示例说明如何在Backbone视图中利用Backbone模型属性。 在js / main.js中 应用程序名称空间已创建。 Backbone架构也将是一个简单JavaScript名称空间。 在js / hello-model.js中 扩展了Backbone模型对象以定义Hello...
使用Backbone模型作为上下文来解析URL模板的极其简单的库。 URL更改时触发更改事件。 var backboneUrlResolver = require ( 'backbone-url-resolver' ) ; var Backbone = require ( 'Backbone' ) ; var context...