预览ExtJS 4.0的新功能(三):客户端数据层的革新:引入ActiveRecord模式

转载请注明出处Ext中文网http://ajaxjs.com)。

Ext JS 4最强大的机能之一就是将模型的关系映射链接到一起。在 Ext 4 数据模型中,这种链接关系是通过关联操作(associations)来完成的。在应用中定义不同物件的关系是非常自然的。比如说,在一个食谱数据库中,一条食谱可能会有多条评论,多条评论又可能为同一作者所写,而作者又可以创造多条食谱。透过定义这种链接关系可以让你以更直观地更强大的方式去操纵数据。

一、预备知识

首先是 belongTo 管关联。何谓“belongTo”,我们不妨这样说(“属于”这里表示特定的关系):

  • 公司数据库中,账单 accout 属于 公司 company;
  • 论坛程序中,帖子 thread 属于论坛 forum,也属于分类 cateory;
  • 一个画册中,缩略图 thumbnail 属于picture。

如果 bar 属于foo,也就是说它们之间的关系 belongTo,那么一般情况下,关系型数据库物理表中,bar 表会有一称作 foo_id 的字段,作为外键(foreign_key)出现。

相对地,与 belongs_to 关联相对应地就是 hasMany 关联,也就是“多对一” v.s “一对多”之间的区别;

也许我们可以借助“父-子”的概念去理解,例如父母可有多个孩子,孩子只有一对父母。账单相当于公司是“子级别”,而公司相当于账单是“父级别”。

当前 Ext.data 可支持 belongTo(多对一)、hasMany(一对多)、多对多。而 hasOne 关系实际上包含在 belongTo 关系中。

二、Model 实例管理器:ModelMgr

例如,假设一个博客的管理程序,有用户 Users、贴子 Posts 和评论 Comments 三大业务对象。我们可以用以下语法表达它们之间的关系:

Edit 2011-9-22 示例代码可能与最新版本的 Ext Model 有区别,但不影响主干意思——感谢 Thanks to QiuQiu/太阳提醒。

通过定义属性 associations 亦可:

在登记模型的过程中,主要执行的程序如下(详细见注释):

三、Ext.data.BelongsToAssociation

Ext.data.Association 表示一对一的关系模型。主模型(owner model)应该有一个外键(a foreign key)的设置,也就是与之关联模型的主键(the primary key)。

上面例子中我们分别创建了 Products 和 Cattegory 模型,然后将它们关联起来,此过程我们可以说产品 Product 是“属于”种类Category的。默认情况下,Product 有一个 category_id 的字段,通过该字段,每个 Product 实体可以与 Category 关联在一起,并在 Product 模型身上产生新的函数。

获得新函数,其原理是通过反射得出的。第一个加入到主模型的函数是 Getter 函数。

在定义关联关系的时候,就为 Product 模型创建了 getCategory 函数。另外一种 getCategory 函数的用法是送入一个包含 success、failure 和 callback 的对象,都是函数类型。其中,必然一定会调用 callback,而 success 就是成功加载所关联的模型后,才会调用的 success 的函数;反之没有加载关联模型,就执行 failure 函数。

以上的回调函数执行时带有两个参数:1、所关联的模型之实例;2、负责加载模型实例的Ext.data.Operation对象。当加载实例有问题时,Operation对象就非常有用。

第二个生成的函数设置了关联的模型实例。如果只传入一个参数到setter那么下面的两个调用是一致的:

如果传入第二个参数,那么模型会自动保存并且将第二个参数传入到主模型的 Ext.data.Model.save 方法:

Model 可以让我们自定义字段参数。若不设置,关联模型的时候会自动根据 primaryKey 和 foreignKey 属性设置。这里我们替换掉了默认的主键(默认为'id')和外键(默认为'category_id')。一般情况却是不需要的。

四、Ext.data.HasManyAssociation

HasManyAssociation 表示一对多的关系模型。如下例:

 

以上我们创建了 Products 和model 模型,我们可以说用户有许多商品。每一个 User 实例都有一个新的函数,此时此刻具体这个函数就是“product”,这正是我们在 name 配置项中所指定的名字。新的函数返回一个特殊的 Ext.data.Store,自动根据模型实例建立产品。

 

所述的 Store 只在头一次执行 product() 时实例化,持久化在内存中不会反复创建。

由于 Store 的 API 中自带 filter 过滤器的功能,所以默认下过滤器告诉 Store 只返回关联模型其外键所匹配主模型其主键。例如,用户 User 是 ID=100 拥有的产品 Products,那么过滤器只会返回那些符合 user_id=100 的产品。

但是有些时间必须指定任意字段来过滤,例如 Twitter 搜索的应用程序,我们就需要 Search 和 Tweet 模型:

例子中的 tweets 关系约等价于下面代码所示,也就是通过 Ext.data.HasManyAssociation.filterProperty 定义过滤器。

数据可能来源于各个地方,但对于我们来说常见的途径是关系型数据库。本节大部分的内容都是基于关系型数据库进行展开的。

五、Ext.data.PolymorphicAssociation

多对多关系(鉴于文档信息不足……略……)

六、小结

相比于服务端的 ActiveRecord 方案,Ext 只是继承,自然没有太多高级的特性。也许客户端的话,仅此而已便足够……但是有没有人想把 Ext.data放到后台跑呢?天啊~难得不是为了……

从技术评估上看,动态语言比较适合实现所谓的 ActiveRecord,4.0 采用 ActiveRecord 的概念也是处于客户端当中的,生成的不是 SQL,而是通过 AJAX 请求之类的请求,可见这一思路丰富了既 ActiveRecord 的内涵,也从一侧面提升了动态语言的价值。

ORM 几乎是所有企业开发项目的标配,但可实现 ORM 的方案和思路却多种多样。虽不能说百花齐放,但也可以说繁荣到可以说争奇斗艳。

(……ORM 讨论若干字……略……见下面补充的链接)

既然选择了 ActiveRecord 去实现,想必也有一定的理由。JS 是动态语言,动态语言的确很容易做出 ActiveRecrod,这是无疑的,起码比静态语言好做。然而是否一定只选择AcitveRecord 呢?也不见得,例如微软的 JSLinq 也是一种思路,我见过有 JavaScript 方案的(虽然都是对 JSON 查询的,却缺少 JS2SQL 的),说明动态语言的优势还是很明显的,语言包袱没那么重。呵呵,不啰嗦,否则又容易扯起“语言之争”。

实际上模型 ActiveRecord 早已久负盛名,可能这就是 ExtJS 开发团队考量的因素之一。Ruby on Rails、Gails 上的 ActiveRecord 已经热闹非凡,JS 或 Ext 至今才实现的话算晚的了……原来我也写过 ActiveRecord 的 JS,当然差得远了,不过这一切都是没有实际项目的“纸上谈兵”有关概念、理论说明等的内容……还须见企业级开发导师马大叔的为准:http://www.martinfowler.com/eaaCatalog/activeRecord.html……上面权且为草草笔记。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sp42a

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值