Ext JS 4倒计时:数据包


数据包在某种意义上来说是Ext JS 4中最完善的地方。数据包可以让你的应用程序对数据进行复用、解码和输出。在Ext JS 4中,数据包已经被重写,但它的使用方法与以前版本的一样。今天,我们将介绍新的数据包,看看它能为我们提供什么。

新特性

Ext JS 4的数据包包含43个类,但有Model 、Store和Proxy相对其它类来说相当重要,这几乎是每一个应用程序都要用到的,而且它有一些卫星类支持。

Models类和Store类

数据包的核心是Ext.data.Model对象。一个模型就代表一个应用程序中的数据类型,例如一个电子商务应用程序可能包含用户、产品和订单等模型。最简单的一个模型只是一个字段和他么数据的集合。任何使用过Ext JS 3的人都会使用到Ext.data.Record,这就是Ext.data.Model的前身。让我们来看看如何创建一个模型:

Ext.regModel('User', {
    fields: [
        {name: 'id', type: 'int'},
        {name: 'name', type: 'string'}
    ]
});

模型通常使用于Store,基本上是一个模型实例的集合。Store的定义和加载很简单,代码如下:

new Ext.data.Store({
    model: 'User',
    proxy: {
        type: 'ajax',
        url : 'users.json',
        reader: 'json'
    },
    autoLoad: true
});

代码中,我们从“users.json”加载了一个用户模型实例。在Store中,我们定义了一个Ajaxproxy,需要为它指定url以加载数据的地址,还要指定Ext.data.Reader解码数据的方式、例子中,服务器将返回json数据,因而我们需要使用JsonReader读取数据。

Store不但支持本地排序、筛选和分组,也支持远程排序、筛选和分组。在Ext JS 4中,不再使用GroupingStroe,我们在标准的Store中就可以实现多列排序、筛选和分组:

new Ext.data.Store({
    model: 'User',
 
    sorters: ['name', 'id'],
    filters: {
        property: 'name',
        value   : 'Ed'
    },
    groupers: {
        property : 'age',
        direction: 'ASC'
    }
});

在代码中,数据将首先根据“name”字段排序,然后再按“id”排序;数据将筛选出“name”字段为“Ed”的数据,并对其按“age”字段进行分组。通过Store API,你可以在任何时间轻松地对数据进行排序、筛选和分组。

Proxies
从上面的代码中可以看到,Store通过Proxy来加载数据以及在Proxy中定义的Reader对服务器返回的数据进行解码。Store在Ext JS 4中一个结构性的变化就是不再直接关联Reader和Writer,这些都将由Proxy处理。这带给了我们一个好处,就是在Model中可以直接定义Proxies:

Ext.regModel('User', {
    fields: ['id', 'name', 'age'],
    proxy: {
        type: 'rest',
        url : '/users',
        reader: {
            type: 'json',
            root: 'users'
        }
    }
});
 
//uses the User Model's Proxy
new Ext.data.Store({
    model: 'User'
});

这带来了两个好处。第一,因为每个使用User模型的Store都使用同一方式加载数据,从而避免了为每个Sotre重复定义Proxy。第二,现在我们不需要通过Store,就可以直接在模型中加载和保存数据了:

//gives us a reference to the User class
var User = Ext.getModel('User');
 
var ed = new User({
    name: 'Ed Spencer',
    age : 25
});
 
//we can save Ed directly without having to add him to a Store first because we
//configured a RestProxy this will automatically send a POST request to the url /users
ed.save({
    success: function(ed) {
        console.log("Saved Ed! His ID is "+ ed.getId());
    }
});
 
//load User 123 and do something with it (performs a GET request to /users/123)
User.load(123, {
    success: function(user) {
        console.log("Loaded user 123: " + user.get('name'));
    }
});

在这里我们需要介绍一下采用HTML 5新功能的代理LocalStorageProxy和SessionStorageProxy。尽管旧的浏览器不支持这些HTML 5的API,但它们非常有用,但它们的存在,会让我们获益良多。如果没有符合你要求的proxy,你可以轻松的创建你需要的Proxy。

模型关联

在模型中定义Proxy不是唯一的新功能,我们现在还可以通过关联API将模型关联起来。大多数应用程序会处理许多不同的模型,而且模型之间是相关的。譬如,一个博客应用包括用户、发布和评论等模型。每个用户发布的文章及它的评论,我们可以这样表达它们之间的关系:

Ext.regModel('User', {
    fields: ['id', 'name'],
 
    hasMany: 'Posts'
});
 
Ext.regModel('Post', {
    fields: ['id', 'user_id', 'title', 'body'],
 
    belongsTo: 'User',
    hasMany: 'Comments'
});
 
Ext.regModel('Comment', {
    fields: ['id', 'post_id', 'name', 'message'],
 
    belongsTo: 'Post'
});

这很容易表达出您的应用程序的不同模型之间的复杂关系。每一个模型不单可以拥有许多关联模型,而且与它们的定义顺序无关。一旦我们有一个模型实例,我们就可以很容易地遍历相关数据。 例如,如果我们想输出一个用户的全部文章的评论,我们可以这样做:

//loads User with ID 123 using User's Proxy
User.load(123, {
    success: function(user) {
        console.log("User: " + user.get('name'));
 
        user.posts().each(function(post) {
            console.log("Comments for post: " + post.get('title'));
 
            post.comments().each(function(comment) {
                console.log(comment.get('message'));
            });
        });
    }
});

每当定义一个hasMany关联的时候,我们都将在模型内增加一个新函数。因为我们在User模型和Posts模型中定义hasMany关联,所以在User模型中增加了上面代码中的user.posts()函数。调用user.posts()将返回一个使用Post模型的Store。同样,因为Post模型和Comments模型建立了hasMany关联,所以在Post模型中可以使用comments函数。

你可能很奇怪,为什么在User.load中需要使用“success”函数,而在post和comments函数中不需要?这是因为所有数据都被假定为从服务器上异步加载的。这意味着当所有数据都已经被加载时,才会回调上面代码的“success”函数。

加载嵌套数据
当我们在建立上面的关联时,框架会自动分析出单个请求中的嵌套数据。譬如我们请求一个User数据,它的Post数据以及每个Post数据的Comments数据都会从一个服务器请求中返回,数据形式如下:

{
    id: 1
    name: 'Ed',
    posts: [
        {
            id   : 12,
            title: 'All about data in Ext JS 4',
            body : 'One of the areas that has seen the most improvement in Ext JS 4...',
            comments: [
                {
                    id: 123,
                    name: 'S Jobs',
                    message: 'One more thing'
                }
            ]
        }
    ]
}

因为这些数据都是通过框架自动分析处理的,因而你可以很方便的配置模型的Proxy从任何地方加载数据以及使用不同的Reader处理不同格式的数据。至于Ext JS 3,Models和Stores都是通过许多组件框架使用的,譬如网格、树和表单。

在线演示和其他
我们已经为你主板了一个简单的在线演示让你体验新的数据包功能。该演示使用了本文模型的设置和对应的数据。你也能下载该演示在本地运行。因为当时还处于测试阶段,因而会有一些bug,但总体来说,数据包处于一个非常强壮的状态。

如果你想了解更多有关新的数据包的功能,我估计你注册我们的新闻列表。我们讲每月发送一次关于Ext JS和Sencha Touch的文章,有些文章是你在其它地方找不到的(包括我们的博客)。

英文原文:Countdown to Ext JS 4: Data Package

翻译:黄灯桥
原文:http://blog.csdn.net/tianxiaode/archive/2011/01/22/6158417.aspx