Sencha Touch学习笔记(四)数据

数据包(Data Package)是负责加载和保存在Sencha Touch应用程序的所有数据。
它涉及到三个部分:model, store, proxy(模型、商店、代理)。
model:model表示你的工程所关心的实体。用户,联系人,地址,和产品都可以被模型。在其最简单的,一个模型只是一个收集的领域和他们的数据,但他们可以做的更多。
store:一个store是一个model实例。它主要是一个阵列,但它也提供了功能分类,过滤,分组,和它能够触发的事件。
proxy:proxy负责实际加载和保存数据到一个store。你通常会创建一个Ajax代理,将数据从服务器获取并使用它来填充一个store。

model

model含有四个主体:Fields, Proxies, Associations and Validations(域、代理、协会、验证)

Fields

这里写图片描述
下面我们就写个简单的例子:

Ext.define('User', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            { name: 'id', type: 'int' },
            { name: 'name', type: 'string' }
        ]
    }
});

写法可参照类,这里只定义了fields,可以指定数据类型。

Proxies

下面来说下代理,代理含有两种:客户端和服务器,客户端包含浏览器内存和本地存储,支持html5的本地存储功能。服务器包括Ajax, JsonP, 和 Rest。

Ext.define('User', {

    extend: 'Ext.data.Model',

    config: {
        fields: ['id', 'name', 'age', 'gender'],
        proxy: {
            type: 'rest',
            url : 'data/users',
            reader: {
                type: 'json',
                root: 'users'
            }
        }
    }
});

// Uses the User Model's Proxy
Ext.create('Ext.data.Store', {
    model: 'User'
});

在创建store时通过指定model:来把自己定义的user实例成store。
将proxy放到model中来是有好处的,当很多store应用一个model时不用重复的指定proxy,而且我们可以加载和保存模型数据而不调用一个存储。

// Gives us a reference to the User class
var User = Ext.ModelMgr.getModel('User');

var ed = Ext.create('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 which 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 1 and do something with it (performs a GET request to /users/1)
User.load(1, {
    success: function(user) {
        console.log("Loaded user 1: " + user.get('name'));
    }
});

通过上面的例子我们知道;我们可以通过Ext.ModelMgr.getModel()这种方式来获取一个已经定义过的model实例。
而且由于已经在model中定义好了proxy,所以无需store可以通过save的方式直接操作数据向url /users发送一个post请求;通过User.load方式,获取到id=1的用户。
也可以使用代理来利用HTML的本地存储和session存储(f HTML5 - LocalStorage and SessionStorage),虽然还有很多浏览器不支持,但它也许在将来发挥巨大的作用。

Associations

model可以通过Associations API连接在一起使用,因为在实际的业务中,好多的model是有些联系的。比如一个博客,有用户,和评论,用户发表评论。我们可以通过下面的例子来表达这些关系:

Ext.define('User', {
    extend: 'Ext.data.Model',
    config: {
        fields: ['id', 'name'],
        proxy: {
            type: 'rest',
            url : 'data/users',
            reader: {
                type: 'json',
                root: 'users'
            }
        },

        hasMany: 'Post' // shorthand for { model: 'Post', name: 'posts' }
    }
});

Ext.define('Comment', {
    extend: 'Ext.data.Model',

    config: {
        fields: ['id', 'post_id', 'name', 'message'],
        belongsTo: 'Post'
    }
});

Ext.define('Post', {
    extend: 'Ext.data.Model',

    config: {
        fields: ['id', 'user_id', 'title', 'body'],

        proxy: {
            type: 'rest',
            url : 'data/posts',
            reader: {
                type: 'json',
                root: 'posts'
            }
        },
        belongsTo: 'User',
        hasMany: { model: 'Comment', name: 'comments' }
    }
});

通过belongsTo:来指定上一级model,通过hasMany来指定下一级model,其中’Post’ 是对 { model: ‘Post’, name: ‘posts’}的简写。
可以看到上面模型的关系,User<-Post<-Comment
那这样定义完了有什么好处呢?这样可以很容易发现你程序中不同模型的复杂关系,一旦你有了一个模型实例,您可以轻松地遍历关联数据。例如,记录所有的评论使每个岗位上为特定的用户,使用代码如下:

// Loads User with ID 1 and related posts and comments using User's Proxy
User.load(1, {
    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'));
            });
        });
    }
});

通过User.load ,得到id=1的用户数据,甚至能够获取到posts和comments.

Associations不仅有助于加载数据,也可以用于创建新记录(records):

user.posts().add({
    title: 'Ext JS 4.0 MVC Architecture',
    body: 'It\'s a great Idea to structure your Ext JS Applications using the built in MVC Architecture...'
});

user.posts().sync();

在这个例子中,我们实例化一个新的Post,然后通过配置的代理叫sync()保存新的Post。这是一个异步操作,当操作完成时你可以通过一个回调来通知你或者做些其他的操作。
以上的部分属于Associations。

最后你还可以再模型中生成新的方法包括异步的方法:

// get the user reference from the post's belongsTo association
post.getUser(function(user) {
    console.log('Just got the user reference from the post: ' + user.get('name'));
});

// try to change the post's user
post.setUser(100, {
    callback: function(product, operation) {
        if (operation.wasSuccessful()) {
            console.log('Post\'s user was updated');
        } else {
            console.log('Post\'s user could not be updated');
        }
    }
});
Validations

我们可以在定义model时同时指定丰富的数据验证规则:

Ext.define('User', {
    extend: 'Ext.data.Model',

    config: {
        fields: [
            // ...
        ],

        validations: [
            { type: 'presence',  field: 'name' },
            { type: 'length',    field: 'name', min: 5 },
            { type: 'format',    field: 'age', matcher: /\d+/ },
            { type: 'inclusion', field: 'gender', list: ['male', 'female'] },
            { type: 'exclusion', field: 'name', list: ['admin'] }
        ],

        proxy: [
            // ...
        ]
    }
});

包括presence 非空验证,length长度,format正则表达式验证,inclusion指定结果集,exclusion排除的结果。
定义好了带有验证的model后我们来使用一下:

// now lets try to create a new user with as many validation errors as we can
var newUser = Ext.create('User', {
    name: 'admin',
    age: 'twenty-nine',
    gender: 'not a valid gender'
});

// validate()来验证我们刚刚创建的User实例
var errors = newUser.validate();

console.log('Is User valid?', errors.isValid()); // 返回验证结果,这里返回false
console.log('All Errors:', errors.items); // 返回所有不符合验证的结果

console.log('Age Errors:', errors.getByField('age')); // 返回指定的age属性的错误

这里的关键功能是validate(),运行所有的配置的验证并返回一个错误对象。

Store

说完了model,我们再来说说store
model通常都是用在store上的:

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

在这个例子中,我们配置了store使用Ajax代理,负载数据提供的URL的名称和读者用于解码数据。在这种情况下,服务器返回的JSON,所以我们建立了一个JSON读取器读取响应。autoLoad:true代表当store加载后就去自动读取数据。
结合着model来看,我们发现proxy可以灵活的配置在model或者store中,这要结合你工程的实际情况来用。
当然,store也可以加载内部数据:

Ext.create('Ext.data.Store', {
    model: 'User',
    data: [
        { firstName: 'Greg',    lastName: 'Barry' },
        { firstName: 'Seth', lastName: 'Lemmons' },
        { firstName: 'Mitch', lastName: 'Simoens' },
        { firstName: 'Fred', lastName: 'Mosby' }
    ]
});

在创建store的同时,我们还可以直接进行排序,分组,过滤:

Ext.create('Ext.data.Store', {
    model: 'User',

    sorters: ['name', 'id'],
    filters: {
        property: 'name',
        value   : 'Ed'
    },
    groupField: 'age',
    groupDir: 'DESC'
});

通过name,id来排序,只查出name=’Ed’数据,以age分组以age降序排列。

Proxy

代理,我们已经穿插的在model和store中讲了。
代理含有两种:客户端和服务器,客户端包含浏览器内存和本地存储,支持html5的本地存储功能。服务器包括Ajax, JsonP, 和 Rest。
可以定义在model中,也可以配置在store中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值