资讯专栏INFORMATION COLUMN

JavaScript MVC 学习笔记(七)模型之ORM

animabear / 1884人阅读

摘要:从技术的角度讲,出于的原因,无法友好正式地生成位的,它只能生成伪随机数。虽然中内置的方法尽管产生的是伪随机数,但也足够用了。

持久化记录

需要一种保持记录持久化的方法,即将引用保存至新创建的实例中以便任何时候都
能访问它。通过在Model 中使用records 对象来实现。当保存一个实例的时候,
就将它添加进这个对象中;当删除实例时,和将它从对象中删除:

</>复制代码

  1. // 用来保存资源的对象
  2. Model.records = {};
  3. Model.include({
  4. newRecord: true,
  5. create: function(){
  6. this.newRecord = false;
  7. this.parent.records[this.id] = this;
  8. },
  9. destroy: function(){
  10. delete this.parent.records[this.id];
  11. }
  12. });

更新一个已存在的实例——只需更新对象引用即可:

</>复制代码

  1. Model.include({
  2. update: function(){
  3. this.parent.records[this.id] = this;
  4. }
  5. });

现在创建一个快捷函数来保存实例,这样就不用每次都检查这个实例是否已经保存过或
是否需要新创建实例了:

</>复制代码

  1. // 将对象存入hash 记录中,保持一个引用指向它
  2. Model.include({
  3. save: function(){
  4. this.newRecord ? this.create() : this.update();
  5. }
  6. });

用来根据ID 查找资源的find() 函数:

</>复制代码

  1. Model.extend({
  2. // 通过ID 查找,找不到则抛出异常
  3. find: function(id){
  4. return this.records[id] || throw("Unknown record");
  5. }
  6. });

现在已经成功地创建了一个基本的ORM,运行一下:

</>复制代码

  1. var asset = Asset.init();
  2. asset.name = "same, same";
  3. asset.id = 1
  4. asset.save();
  5. var asset2 = Asset.init();
  6. asset2.name = "but different";
  7. asset2.id = 2;
  8. asset2.save();
  9. assertEqual( Asset.find(1).name, "same, same" );
  10. asset2.destroy();
增加 ID 支持

此时每次保存一条记录都必须手动指定一个ID。可以加入自动化处理。首先,我们需要一个方法来自动生成ID,可以使用全局统一标识(Globally UniqueIdentifier,简称GUID)生成器来做这一步。从技术的角度讲,出于API 的原因,JavaScript 无法友好正式地生成128 位的GUID,它只能生成伪随机数。虽然JavaScript 中内置的Math.random() 方法尽管产生的是伪随机数,但也足够用了。

Robert Kieffer 写了一个简单明了的GUID 生成器,它使用Math.random() 来产生一个伪
随机数的GUID(http://goo.gl/0b0hu),代码也很简单:

</>复制代码

  1. Math.guid = function(){
  2. return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
  3. var r = Math.random()*16|0, v = c == "x" ? r : (r&0x3|0x8);
  4. return v.toString(16);
  5. }).toUpperCase();
  6. };

现在有了生成GUID 的方法,可以很容易将它集成到ORM 里,剩下的只需修改
create() 函数了:

</>复制代码

  1. Model.extend({
  2. create: function(){
  3. if ( !this.id )
  4. this.id = Math.guid();
  5. this.newRecord = false;
  6. this.parent.records[this.id] = this;
  7. }
  8. });

这样任何新创建的记录都包含一个随机的GUID 作为它们的ID :

</>复制代码

  1. var asset = Asset.init();
  2. asset.save();
  3. asset.id //=> "54E52592-313E-4F8B-869B-58D61F00DC74"
寻址引用

目前创建的ORM 中存在一个与引用相关的bug。当保存或
通过find() 查找记录时,所返回的实例并没有复制一份,因此对任何属性的修改都会影
响原始资源。改进:

</>复制代码

  1. var asset = new Asset({name: "foo"});
  2. asset.save();
  3. // 正确传入资源
  4. assertEqual( Asset.find(asset.id).name, "foo" );
  5. // 更改属性,而没有调用update()
  6. asset.name = "wem";
  7. // 出问题了,因为asset 的名字被修改为“wem”
  8. assertEqual( Asset.find(asset.id).name, "foo" );

需要修复这个问题,在执行find() 操作的时候新创建一个对象,同样在创建或更新
记录的时候需要复制对象:

</>复制代码

  1. Asset.extend({
  2. find: function(id){
  3. var record = this.records[id];
  4. if ( !record ) throw("Unknown record");
  5. return record.dup();
  6. }
  7. });
  8. Asset.include({
  9. create: function(){
  10. this.newRecord = false;
  11. this.parent.records[this.id] = this.dup();
  12. },
  13. update: function(){
  14. this.parent.records[this.id] = this.dup();
  15. },
  16. dup: function(){
  17. return jQuery.extend(true, {}, this);
  18. }
  19. });

这里存在另外一个问题,Model.records 是被所有模型所共享的对象:

</>复制代码

  1. assertEqual( Asset.records, Person.records );

但这在合并所有的记录时会有副作用:

</>复制代码

  1. var asset = Asset.init();
  2. asset.save();
  3. assert( asset in Person.records );

解决办法是在创建新的模型时设置一个新的records 对象。Model.create() 是创建新对
象的回调,因此我们可以设置任意描述这个模型的对象:

</>复制代码

  1. Model.extend({
  2. created: function(){
  3. this.records = {};
  4. }
  5. });

【公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。】

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85576.html

相关文章

  • JavaScript MVC 学习笔记(六)模型ORM

    摘要:模型应当从视图和控制器中解耦出来。与数据操作和行为相关的逻辑都应当放入模型中,通过命名空间进行管理。在应用中,对象关系映射也是一种非常有用的技术,它可以用来做数据管理及用做模型。以基于的富应用开发为主要学习资料。 MVC 和命名空间 要确保应用中的视图、状态和数据彼此清晰分离,才能让架构更加整洁有序且更加健壮。模型应当从视图和控制器中解耦出来。与数据操作和行为相关的逻辑都应当放入模型...

    mrcode 评论0 收藏0
  • JavaScript MVC 学习笔记(一)初识JS MVC

    摘要:以基于的富应用开发为主要学习资料。下面用实现一个例子使用匿名函数来封装一个作用域在页面加载时绑定事件监听上面的代码创建了控制器,这个控制器是放在变量下的命名空间。然后用了一个匿名函数封装了一个作用域,以避免对全局作用域造成污染。 公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。 什么是MVC MVC 是一种设...

    xorpay 评论0 收藏0
  • Deep in JS - 收藏集 - 掘金

    摘要:今天同学去面试,做了两道面试题全部做错了,发过来给道典型的面试题前端掘金在界中,开发人员的需求量一直居高不下。 排序算法 -- JavaScript 标准参考教程(alpha) - 前端 - 掘金来自《JavaScript 标准参考教程(alpha)》,by 阮一峰 目录 冒泡排序 简介 算法实现 选择排序 简介 算法实现 ... 图例详解那道 setTimeout 与循环闭包的经典面...

    enali 评论0 收藏0
  • 我的Android重构旅:架构篇

    摘要:是的架构的实现。是在年提出的一种前端架构,主要用来处理复杂的逻辑的一致性问题当时是为了解决页面的消息通知问题。 去年10月底来到了新公司,刚开始接手 Android 项目时,发现该项目真的是一团遭,项目开发上没有任何架构可言,开发人员连简单的 MVC、MVP 都不了解,Activity 及其臃肿,业务边界也不明确,因此我决定重新分析一下当前主流的几种开发架构,选出适合当前项目的架构形式...

    mylxsw 评论0 收藏0
  • Backbone.js学习笔记(一)

    摘要:它通过数据模型进行键值绑定及事件处理,通过模型集合器提供一套丰富的用于枚举功能,通过视图来进行事件处理及与现有的通过接口进行交互。 本人兼职前端付费技术顾问,如需帮助请加本人微信hawx1993或QQ345823102,非诚勿扰 1.为初学前端而不知道怎么做项目的你指导 2.指导并扎实你的JavaScript基础 3.帮你准备面试并提供相关指导性意见 4.为你的前端之路提供极具建设性的...

    FrancisSoung 评论0 收藏0

发表评论

0条评论

animabear

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<