mvc-3模型和数据(2)

寻址引用

源代码现存的问题:当保存或通过find()查找记录时,所返回的实例并没有复制一份,因此对任何属性的修改都会影响原始资源;这里我们只想当调用update()方法时才会修改资源

//由于Model.records时所有模型所共享的,所以在创建新的模型时设置一个新的records对象;
Model.extend({
  created: function() {
    this.records = {};
  }
});
var Asset = Model.create();

//添加到的是每个类对象里,所有不共享
//在执行find时创建一个对象,同样在创建或更新记录时需要复制对象;
Asset.extend({
  find: function(id) {
    var record = this.records[id];
    if(!record) throw("Unknow record");
    return record.dup();
  }
});
//添加到的是每个类对象的prototype属性里,所有该类init的'实例'共享
Asset.include({
  create: function() {
    this.newRecord = false;
    this.parent.records[this.id] = this.dup();
  },
  update: function() {
    this.parent.records[this.id] = this.dup();
  },
  //深度复制
  dup: function() {
    return jQuery.extend(true, {}, this);
  }
});


var asset = Asset.init({name: 'foo'});
asset.save();

console.log(Asset.find(asset.id));
asset.name="new";
console.log(Asset.find(asset.id));
asset.update();
console.log(Asset.find(asset.id));

转载数据

  • 数据的预加载:如

    • 一个可翻页列表的时候,预加载下一页的数据
    • 长列表的时候,当滚动到一定位置就自动加载并插入数据
  • 加载数据方式

    • 直接嵌套显示在初始页面
    • 通过Ajax或Jsonp的方式用单独的HTTP请求加载数据

直接嵌套数据

  • 推荐只在数据量少的时候使用

通过Ajac载入数据

同源策略限制:因为当一个Ajax请求被发送时,所有的请求都会附带主域的cookie信息一起发送;所有如果请求是来自域登录后的用户,没有同源策略限制,攻击者就可能获取你的重要信息

JSONP

原理是通过创建一个script标签,所辖的外部文件包含一段JSONP数据,数据是由服务器返回的,作为参数包装在一个函数调用中

//指向一个远程服务
<script src="http://example.com/data.json"></script>
//请求文件中包含json对象
jsonCallback({"data": "foo"});
//本地s设置运行
window.jsonCallback = function(rest) {
  //....	
}

向ORM中添加记录

从服务器抓取记录并更新模型记录

Model.extend({
  populate: function(values) {
    this.records = {};
    for(var i = 0, l = values.length; i < l; i++) {
      var record = this.init(values[i]);
      record.newRecord = false;
      this.records[record.id] = record;
    }
  }
});

//请求数据
jQuery.getJSON("/assets", function(result) {
  Asset.populate(result);
});

本地存储数据

  • 方法

    • localStorage["someData"] = "wen"; //设置一个值
    • var itemsStored = localStorage.length; //获取个数
    • localStorage.setItem("someData", "wem") //设置一个项(一种hash写法)
    • localStorage.getItem("someData"); //获取一个项,不存在返回null;
    • localStorage.removeItem("someData"); //删除一个项,不存在返回null;
    • localStorage.clear(); //清空本地储存;
  • 数据类型的处理

    • 由于保存的都是字符串,如果要保存数字或对象,必须自己转化类型;

    • 如果使用json,需要储存的时候将对象序列化,取出的时候再转化

      var object = {some: "object"};
      localStorage.setItem("seriData", JSON.stringify(object));
      var result = JSON.parse(localStorage.getItem("SeriData"));
      
  • 给ORM添加本地存储

//为了实现本地存储,首先判断哪些属性需要序列化;
Model.extend({
  created: function() {
    this.records = {};
    this.attributes = [];
  }
});

Model.include({
//创建attributes函数用以返回包含属性到值的映射的对象;  
  attributes: function() {
    var result = {};
    for(var i in this.parent.attributes) {
      var attr = this.parent.attributes[i];
      result[attr] = this[attr];
    }
    result.id = this.id;
    return result;
  },
  toJSON: function() {
    return (this.attributes());
  }
});
//增加两个方法,当保存数据的时候,Model.records对象将转化为数组,做序列化并储存到本地
Model.LocalStorage = {
  saveLocal: function(name) {
    var result = [];
    for(var i in this.records) {
      result.push(this.records[i])
    }

    localStorage[name] = JSON.stringify(result);
  },
  localLocal: function(name) {
    var result = JSON.parse(localStorage[name]);
    this.populate(result);
  }
};

var Person = Model.create();
Person.extend(Model.LocalStorage);
Person.attributes = ["name", "ext"];

var jinks = Person.init({name: "jinks", age:24});
jinks.save();
var bob = Person.init({name: "bob", age:24});
bob.save();

var json = JSON.stringify(Person.records);

console.log(jinks.attributes(), json);

Person.saveLocal("user");

将新纪录提交给服务器

Model.include({
  createRemote: function(url, callback) {
    $.post(url, this.attributes(), callback);  
  },
  updateRemote: function(url, callback) {
    $.ajax({
      url: url,
      data: this.attributes(),
      success: callback,
      type: "PUT"
    })
  }
})

var Person = Model.create();

Person.init({name: "json.text"}).createRemote("/assets");
原文地址:https://www.cnblogs.com/jinkspeng/p/4227234.html