Backbone模型

Backbone模型

现在进入最关键的组件 - 模型。模型用来存储应用的所有数据,以及直接和数据操作相关的逻辑。Backbone中的模型类是Backbone.Model,它包含了数据存储,数据验证,以及数据发生变动时触发相关动作。

一般可以把模型与后端绑定(ORM),模型改变的同时向后端发起请求(Ajax)更新数据(数据库)。也有把模型和DOM元素绑定,模型改变时更新HTML界面。

模型

可以直接new一个Backbone.Model,它返回一个Model实例


1

2

var model = new Backbone.Model()

model.set({name: ‘Backus‘, age: 35})

也可扩展Backbone.Model,定义自己的模型类(构造器)


1

2

3

4

5

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的属性


1

2

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方法,那么每次设置时将调用该方法进行校验,校验未通过将不进行后续设置,而直接返回。


1

2

3

4

5

6

7

8

9

10

11

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方法,该方法如下


1

2

3

4

5

6

7

8

_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”事件,如下


1

2

3

4

p1.on(‘change‘function(model, error) {

    console.log(‘attributes has changed‘)

})

p1.set({name: ‘Backus‘, age: 87})

你可以在回调函数中去更新视图或处理特定的业务逻辑。如果你显示设置第三个参数中silent为true,将不会触发“change”事件。


1

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,直接返回,见源码


1

2

3

4

5

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)

如下


1

2

3

var p1 = new Person()

p1.save({name: ‘Backus‘, age: 87}) // create

p1.save({name: ‘John‘}) // update

3. 可以传success和error两个回调函数以处理保存成功与失败场景


1

2

3

4

5

var p1 = new Person()

p1.save({name: ‘Backus‘, age: 87}, {

    success: function() {},

    error: function() {}

})

4. 事件,save成功后会依次触发模型的“change”、“request”、“sync”事件。如果监听了这些事件,那么回调将得到执行

从服务器获取模型 - fetch

从服务器端获取使用fetch方法,fetch方法很短


1

2

3

4

5

6

7

8

9

10

11

12

13

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。如下


1

2

3

4

var p1 = new Person()

p1.on(‘change:name‘function(model, error) {

    console.log(‘name has changed‘)

})

控制台中分别设置下name和age

可以看到,只有设置name时才触发事件。

除了Backbone.Model自身提供的事件,你还可以给自己的Model添加自定义的事件以满足需求。

鸟瞰图

1. 内部状态,各属性影响的方法

2. 构造器执行流程

时间: 2024-10-18 17:36:40

Backbone模型的相关文章

backbone模型层浅析

Model层有两个类: Model, Collection 1.Model 不翻文档,我们用代码说话. 首先分析下类. var myM = Backbone.Model.extend({})//构造一个Model类,myM 这个类居然是空的,没有官方所说的那么多属性啊,难道underscore失灵了? >_.keys(myM) ["extend", "__super__"] >_.keys(Backbone.Model) ["extend&qu

【转】Backbone.js学习笔记(二)细说MVC

文章转自: http://segmentfault.com/a/1190000002666658 对于初学backbone.js的同学可以先参考我这篇文章:Backbone.js学习笔记(一) Backbone源码结构 1: (function() { 2: Backbone.Events // 自定义事件 3: Backbone.Model // 模型构造函数和原型扩展 4: Backbone.Collection // 集合构造函数和原型扩展 5: Backbone.Router // 路由

初探Backbone

Backbone简介 中文API:http://www.csser.com/tools/backbone/backbone.js.html 英文API:http://backbonejs.org/ Backbone是构建javascript应用程序的一个优秀的类库.他简洁.轻量级.功能实在. backbone采用MVC模式,本身提供了模型.控制器和视图从而我们应用程序的骨架便形成. backbone依赖于underscore,他是一个类库,提供了60多个函数处理数组操作.函数绑定,以及javas

使用Backbone.js, ExpressJS, node.js, MongoDB的web应用样板工程

这是web应用的一个完整的样板工程,用到了Backbone.js & Marionette, node.js & ExpressJS,MongoDB & Moogoose, Handlebars, Grunt.js, Bower和Browserify! 我建立了一个超级基础的单页面应用程序(SPA),就是一个简单的通讯录管理器, 但麻雀虽小,五脏俱全.我写这篇文章的目的是介绍一下这个应用所用到的整个技术栈:后端,数据,前端,工具和测试.主要包括下面这些技术: 后端: node.js

Backbone与Angular的比较

Backbone与Angular的比较 作者 Victor Savkin ,译者 邵思华 发布于 2014年1月17日 | 注意:QCon全球软件开发大会(北京)2016年4月21-23日,了解更多详情!4 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 稍后阅读 我的阅读清单 将不同的思想和工具进行对比,是一种更好地理解它们的方式.在本文中,我首先将列举在创建web应用程序时需要重复进行的各项任务,随后为你展现Backbone和Angular将如何帮助你完成这些工作.

201507271255_《Backbone之二——使用Backbone八条建议 》

1. 数据不要存在试图view中或dom中,存储在model中. 新建model: this.viewState = new Backbone.Model(); 2. 关于backbone中Mvc中的c.backbone中的mvc中的c是指:collection——提供一些丰富的API用于枚举功能,用于枚举型. 3. Dom事件只改变model 4. Dom只有在model发生改变时才改变 this.listenTo(this.stateModel, 'change', this.render)

【译】别学框架,学架构

前段时间,我有过一次非常有趣的谈话.有个同事站出来支持Angular,他说Angular加快了Web开发的速度.我已经开发复杂的web服务超过10年了,曾经在Microsoft工作,也曾在Cyprus为Spotware工作.目前,我为硅谷的一个初创公司编写应用程序.总的来说,我会顺应潮流.但我感觉自己像只恐龙,因为在我看来使用前端框架没有什么意义,但它被证明是主流.在2014年,我投入到Angular.Knockout和Backbone的世界中.如果你想弄清楚我从中得到了什么,为什么停止使用它们

别学框架,学架构

前段时间,我有过一次非常有趣的谈话.有个同事站出来支持Angular,他说Angular加快了Web开发的速度.我已经开发复杂的web服务超过10年了,曾经在Microsoft工作,也曾在Cyprus为Spotware工作.目前,我为硅谷的一个初创公司编写应用程序.总的来说,我会顺应潮流.但我感觉自己像只恐龙,因为在我看来使用前端框架没有什么意义,但它被证明是主流.在2014年,我投入到Angular.Knockout和Backbone的世界中.如果你想弄清楚我从中得到了什么,为什么停止使用它们

Perseus-BERT——业内性能极致优化的BERT训练方案

[作者] 笋江(林立翔) 驭策(龚志刚) 蜚廉(王志明) 昀龙(游亮) 一,背景--横空出世的BERT全面超越人类2018年在自然语言处理(NLP)领域最具爆炸性的一朵"蘑菇云"莫过于Google Research提出的BERT(Bidirectional Encoder Representations from Transformers)模型.作为一种新型的语言表示模型,BERT以"摧枯拉朽"之势横扫包括语言问答.理解.预测等各项NLP锦标的桂冠,见图1和图2.