Backbone基础(一):模型(Model)

无主题博客 » 前端开发 » Backbone » Backbone基础(一):模型(Model)

Backbone模型是任何应用的核心,包含应用程序里的数据以及与数据相关的逻辑:转换、验证、计算属性和访问控制。我们可以用特定的方法扩展Backbone.Model,Model也提供了一组基本的管理变化的功能。

简单示例

通过Backbone.Model来创建该模型,代码如下:

//创建名为MyModel的模型
var MyModel = Backbone.Model.extend({});

//创建一个具体实例
var m1 = new MyModel();
console.log(JSON.stringify(m1));
//Log 信息: {}

//创建一个带数据的实例
var m2 = new MyModel({"title":"通过实例化设置的标题","completed":true});
console.log(JSON.stringify(m2));
//Log信息:{"title":"通过实例化设置的标题","completed":true}

初始化

创建一个新模型实例的时候,initialize()方法会被调用。该方法是可选的。

var MyModel = Backbone.Model.extend({
  initialize : function(){
    console.log("模型被初始化。");
  }
});

var myModel = new MyModel();
//Log 信息:模型被初始化。

默认值

很多时候,我们想让模型拥有一组默认值(例如,一个所有数据都不是由用户提供的场景)。可以通过使用模型里的defaults属性来设置默认值。

var MyModel = Backbone.Model.extend({
  defaults: {
    title:'',
    completed: false
  }
});
//创建一个具体实例
var m1 = new MyModel();
console.log(JSON.stringify(m1));
//Log 信息:{"title":"","complated":false}

//创建一个实例并赋予属性
var m2 = new MyModel({
  "title":"通过实例化设置的标题",
  "complated":true
});
console.log(JSON.stringify(m2));
//Log 信息:{"title":"通过实例化设置的标题","complated":true}

赋值与取值

Model.get()

Model.get()用于访问模型的属性。

var MyModel = Backbone.Model.extend({
  defaults: {
    title:'',
    completed: false
  }
});

var m1 = new MyModel();
console.log(m1.get("title")); //empty String
console.log(m1.get("complated")); //false

var m2 = new MyModel({
  "title":"通过实例化设置的标题",
  "complated":true
});
console.log(m2.get("title")); //Log:通过实例化设置的标题
console.log(m2.get("complated")); //Log:true

如果我们需要读取或者复制一个模型的所有数据属性,可以使用该模型的toJSON()方法。该方法将所有属性的副本作为一个对象进行返回(注意不是Json字符串)。

var MyModel = Backbone.Model.extend({
  defaults: {
    title:'',
    completed: false
  }
});

var m1 = new MyModel();
var myModelAttributes = m1.toJSON();
console.log(myModelAttributes);
//Log 信息:{"title":"","complated":false}

Model.set()

Model.set()方法是在模型上设置一个包含一个或多个属性的Hash散列,当其中的任意属性更改模型的状态时,就会在上面出发change事件。每个属性的change事件也可以在模型上进行触发和绑定。

var MyModel = Backbone.Model.extend({
  defaults: {
    title:'',
    completed: false
  }
});
//实例化一个实例并设置title属性
var myModel = new MyModel({
  "title":"通过实例化设置的标题"
});
console.log('MyModel Title:' + myModel.get('title'));
//MyModel Title:通过实例化设置的标题
console.log('Completed:' + myModel.get('completed'));
//Completed:false

//使用Model.set()方法设置属性
myModel.set("title","这是通过set方法设置的标题");
console.log('MyModel Title:' + myModel.get('title'));
//MyModel Title:这是通过set方法设置的标题
console.log('Completed:' + myModel.get('completed'));
//Completed:false

//使用Model.set()方法设置属性map集合
myModel.set({
  "title","这是通过set方法(map方式)设置的标题",
  "completed":true
});
console.log('MyModel Title:' + myModel.get("title"));
//MyModel Title:这是通过set方法(map方式)设置的标题
console.log('Completed:' + myModel.get("completed"));
//Completed:true

直接访问

模型暴露了一个.attributes属性,描述了包括该模型状态的一个hash散列。通常和服务器返回数据的JSON对象的形式一样,但也可以采用其他形式。
如果通过模型上的.attributes属性设置值,可以绕过该模型上绑定的触发器。

监听模型变化

模型改变的时候,如果我们想收到一个通知,可以通过监听该模型上的change事件来实现。增加监听器的地方就是initialize()函数中,代码如下:

var MyModel = Backbone.Model.extend({
  defaults: {
    title:'',
    completed: false
  },

  initialize: function(){
    console.log("模型被初始化...");
    this.on('change',function(){
      console.log(' - 模型的属性值发生了变化')
    });
  }
});

var myModel = new MyModel();
myModel.set('title','通过set方法设置标题触发监听器');
console.log('Title:' + myModel.get('title'));

myModel.set('completed',true);
console.log('Completed:' + myModel.get('completed'));

myModel.set({
  title:'同时改变多个属性仅出发一次监听器',
  completed:true
});

//以上运行结果Log信息:
//模型被初始化...
// - 模型的属性值发生了变化
//Title:通过set方法设置标题触发监听器
// - 模型的属性值发生了变化
//Completed:true
// - 模型的属性值发生了变化

在Backbone模型中,我们也可以监听单个属性的改变,在下面的示例中,当特定属性改变时,我们记录对应的信息。

var MyModel = Backbone.Model.extend({

  defaults: {
    title:'',
    completed: false
  },

  initialize: function(){
    console.log("模型被初始化...");
    this.on('change:title',function(){
      console.log(' - 模型的title属性值发生了变化')
    });
  },

  setTitle: function(newTitle) {
    this.set({title:newTitle});
  }
});

var myModel = new MyModel();
myModel.set('title','通过set方法设置标题');
myModel.setTitle('通过setTitle方法设置标题');
myModel.set('completed',true);
console.log('Completed:' + myModel.get('completed'));

//以上运行结果Log信息:
//模型被初始化...
// - 模型的title属性值发生了变化
// - 模型的title属性值发生了变化
//Completed:true

验证

Backbone支持通过model.validate()进行模型验证,允许在设置属性值之前对属性值及in行检查。默认情况下,通过调用save()方法或带有{validate:true}参数的set()方法持久化模型时,验证就会触发。

var Person = new Backbone.Model({name: 'Frank'});
//验证模型的名称
Person.validate = function(attrs){
  if (!attrs.name) {
    return '我需要一个名字';
  }
};
//修改名字
Persion.set({name:"Lincoln"});
console.log(Person.get('name')); //Lincoln
//移除name属性,强制验证
Person.unset('name',{validate:true}); //false

模型中也可以使用unset()方法,通过删除模型内部的属性hash散列,从而达到删除该属性的目的。

如果为模型提供的属性都是有效的,.validate()不会返回任何值;相反,如果参数是无效的,就会返回一个错误值。

当有错误值返回,则:

  • model会触发invalid事件,同时会将.validate()的返回值付给validationError属性。
  • .save()不会继续执行,同时model上的属性不会在服务器上修改。

下面是一个更加完整的例子

var MyModel = Backbone.Model.extend({

  defaults: {
    completed: false
  },

  validate: function(attrs){
    if(attrs.title == undefined) { 
      return "我需要一个标题";
    }
  }

  initialize: function(){
    console.log("模型被初始化...");
    this.on('invalid',function(model, error){
      console.log(error)
    });
  },
});

var myModel = new MyModel();
myModel.set('completed',true,{validate:true});
//Log信息:我需要一个标题
console.log('Completed:' + myModel.get('completed')); //Complted:false

发表评论

电子邮件地址不会被公开。 必填项已用*标注