Backbone中的Model

Backobone是一个JavaScript的前端框架,使具有复杂交互的页面实现能更加清晰。其中Model是核心的部分,它主要主要有下面几个方面:

  • 控制着Backbone中View呈现的内容
  • 与Backbone中Collection的交互
  • 承载着校验,数据运算等功能
  • 与服务端交互的桥梁

Backbone代码一个很显著的特点就是看到满篇的this.model,对新手来说理解这里的model到底是什么以及怎么样传递,什么时候要toJSON,什么时候直接传递,有一点不够直接。这里主要来介绍一下在Model与Collection和View通信中容易混淆的一些场景,希望有所帮助。

Model与View

Backbone中的View主要用来展示Model以及绑定各种事件回掉。View需要与Model绑定可以有两种方式。

  1. 通过构造函数初始化
1
2
3
4
5
6
7
  var PostView = Backbone.View.extend();
  var Post = Backbone.Model.extend();
  var post = new Post({title: "post title"});

  var postView = new PostView(post);
  var anotherPostView = new PostView({model: post});
  var anotherPostView2 = new PostView({model: post.toJSON()});

上面的代码都是通过构造函数将model传如一个View中,唯一的不同是postView是直接传入model对象,anotherPostView是传入了一个hash对象,key值为model,而anotherPostView2则是将post转换为JSON后传入。

这三种有什么不同呢?

Backbone的View构造函数可以接受参数,默认传入的参数可通过this.options来访问,postView就是这种情况。

但是一些特别的参数例如model(其他的参数还有collection, el, id, className,tagName和attributes),如果anotherPostView,model会直接添加到View对象中,可以通过this.model调用,这时的结果是整个post对象,拥有Backbone Model的所有方法。获取title的方式是this.model.get(‘title’)

anotherPostView2与anotherPostView不同在于model被转化为了JSON对象,所以获取title的方式为this.model.title。

那么应当选取哪一种呢?

三种方式都可以满足基本的数据展示需求,只是调用方式的不同,不过推荐使用第二种,因为完整的model对象拥有更完整的事件机制。比如,希望在model改变的时候重新渲染view,那么就可以通过下面的方式

1
  this.model.on('change', this.render, this);

这样的基础是,当通过set改变model的属性时,会自动出发change事件。

  1. 通过render方法传入model

View最重要的方法就是render,它决定如何展现数据。稍微复杂一些的View通常会通过underscore的template方法生成DOM模板,然后传入Model替换其中的Pleaceholder。例如Backbone的网站上给出的例子。

1
2
3
4
5
6
7
  var Bookmark = Backbone.View.extend({
    template: _.template(),
    render: function() {
      this.$el.html(this.template(this.model.attributes));
      return this;
    }
  });

这里的model可以在render方法中传入,然后进一步传入模板中。注意,传入模班的model调用了attributes方法,也就是toJSON,因为在模板中通常直接调用JSON中的key。

那么这两种model与view的关联方式如何取舍呢?我的经验是,如果View只服务于特定的model,那么就在构造函数传入。如果随着model的不同,我们希望这个View可以渲染不同的模板,而View是同一个对象,那么就在render时调用,需要的话在render方法中使用

1
  this.model = model

将传入的model应用于当前View的model。

Model与Collection

Collection是Backbone中一组有序的Model集合,当页面需要管理多个同种类型的Model时,Collection提了很多的便利,例如很多的集合操作,基于集合的事件。Collection可以指定包含的model对象类型,例如

1
2
3
4
5
6
7
var Posts = Backbone.Collection.extend({
  model: Post
});

var posts = new Posts();
posts.add(post);
posts.add({title: "a new post"});

前三行定义了一个Post的Collection,后面向其中添加了两个post,一个是Model对象,一个是hash对象。虽然添加的方式不同,但是当被添加到集合之后,它们的存储都是一样的,因为hash对象会被转换为对应的model对象,如果model定义了initialize方法,还会去调用它。相对于View与Model,Collection与Model的关联方式要简单许多。

这里简单的分析了view与collection中的model用法,相信即使对backbone不是了解,现在看到满篇的this.model应该不会头疼了。

comments powered by Disqus