資料
Ext JS的data包有41個類,最重要的就是Model,Store 和Ext.data.proxy.Proxy這三個了。
Ext JS 4 的資料包:
Models 和 Stores
Ext.data.Model是資料包的核心。一個Model代表應用程式的一些類型的資料。比如,一個電子商務應用程式可能含有 User,Products 和Orders 這樣的Model.最簡單的Model就是一組欄位和值。這裡著重介紹Model的四個基本的組成部分-Fields,Proxies,Associations 和 validations.
來看看如何定義一個model 的簡單樣本:
Ext.define('User', { extend: 'Ext.data.Model', fields: [ { name: 'id', type: 'int' }, { name: 'name', type: 'string' } ]});
Model 定義之後如何使用呢? Model 最典型的是被一個Stroe使用, 以下是建立一個store 和載入資料的例子:
Ext.create('Ext.data.Store', { model: 'User', proxy: { type: 'ajax', url : 'users.json', reader: 'json' }, autoLoad: true});
這裡使用Ajax Proxy 作為Store的資料來源,配置了url 和 Reader(用於解碼資料)。
這個Store 自動通過url(user.json)從服務端載入model 為User 的資料,服務端返回的JSON資料應該是如下格式:
{ success: true, users: [ { id: 1, name: 'Ed' }, { id: 2, name: 'Tommy' } ]}
內聯資料
Stores 也可以內聯的方式載入資料。Store 回把傳入的資料轉換成 model, 如:
Ext.create('Ext.data.Store', { model: 'User', data: [ { firstName: 'Ed', lastName: 'Spencer' }, { firstName: 'Tommy', lastName: 'Maintz' }, { firstName: 'Aaron', lastName: 'Conran' }, { firstName: 'Jamie', lastName: 'Avins' } ]});
排序和分組
類似遠端伺服器的排序,過濾和分組,Stores 也可以在本地用戶端進行排序,過濾和分組。
Ext.create('Ext.data.Store', { model: 'User', sorters: ['name', 'id'], filters: { property: 'name', value : 'Ed' }, groupField: 'age', groupDir: 'DESC'});
在這個例子中,這個store先用name排序,再用 id排序。 只包含name="Ed"的資料,用age欄位逆序排列。
代理
Proxies(代理)用來處理載入和儲存Model 資料。有兩種類型的代理: 用戶端的和服務端的。用戶端代理的例子有使用瀏覽器緩衝來儲存資料和使用HTML 5本機存放區特性來進行的本機存放區。服務端代理處理遠端伺服器返回的資料,比如Ajax,JsonP 和Rest.
代理可以直接定義在一個Model上, 像:
Ext.define('User', { extend: 'Ext.data.Model', fields: ['id', 'name', 'age', 'gender'], proxy: { type: 'rest', url : 'data/users', reader: { type: 'json', root: 'users' } }}); // Uses the User Model's ProxyExt.create('Ext.data.Store', { model: 'User'});
這樣做有兩個好處:
首先是這樣的寫法保證了所有使用User 這個Model的Store 都以同樣的方式載入資料,避免在每個Store中重複定義Proxy;
其次,這樣寫可以在不使用store的狀況下,載入和儲存Model 資料。如下例
// Gives us a reference to the User classvar 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 this will automatically send a POST request to the url /usersed.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')); }});
LocalStorage 和SessionStorage. (HTML5相關的本機存放區)
關聯(Associations)
可以使用關聯的API 建立Models之間的關係。大多數的應用程式都有很多模型,而且模型之間基本上都是有關聯的。舉部落格程式這樣的例子來說,每個使用者可以發表多篇博文:
Ext.define('User', { extend: 'Ext.data.Model', fields: ['id', 'name'], proxy: { type: 'rest', url : 'data/users', reader: { type: 'json', root: 'users' } }, hasMany: 'Post' // shorthand for { model: 'Post', name: 'posts' }}); Ext.define('Post', { extend: 'Ext.data.Model', fields: ['id', 'user_id', 'title', 'body'], proxy: { type: 'rest', url : 'data/posts', reader: { type: 'json', root: 'posts' } }, belongsTo: 'User', hasMany: { model: 'Comment', name: 'comments' }}); Ext.define('Comment', { extend: 'Ext.data.Model', fields: ['id', 'post_id', 'name', 'message'], belongsTo: 'Post'});
定義完成之後,在模型執行個體中就很容易能得到這些關聯資料:如
// Loads User with ID 1 and related posts and comments using User's ProxyUser.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.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();
也可以如下方法使用:
// get the user reference from the post's belongsTo associationpost.getUser(function(user) { console.log('Just got the user reference from the post: ' + user.get('name'))}); // try to change the post's userpost.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'); } }});
載入嵌套資料
關聯資料也可以直接使用以下方式:
{ success: true, users: [ { id: 1, name: 'Ed', age: 25, gender: 'male', posts: [ { id : 12, title: 'All about data in Ext JS 4', body : 'One areas that has seen the most improvement...', comments: [ { id: 123, name: 'S Jobs', message: 'One more thing' } ] } ] } ]}
架構會自動的解析這個資料。
驗證
還是用上面User 模型為例:
Ext.define('User', { extend: 'Ext.data.Model', fields: ..., validations: [ {type: 'presence', name: 'name'}, {type: 'length', name: 'name', min: 5}, {type: 'format', name: 'age', matcher: /\d+/}, {type: 'inclusion', name: 'gender', list: ['male', 'female']}, {type: 'exclusion', name: 'name', list: ['admin']} ], proxy: ...});
presence -- 非空判斷。0 是合法值,空字串不是。
inclusion: -- 一組特定的值
定義完成之後,如何使用:
// now lets try to create a new user with as many validation errors as we canvar newUser = Ext.create('User', { name: 'admin', age: 'twenty-nine', gender: 'not a valid gender'}); // run some validation on the new user we just createdvar errors = newUser.validate(); console.log('Is User valid?', errors.isValid()); //returns 'false' as there were validation errorsconsole.log('All Errors:', errors.items); //returns the array of all errors found on this model instance console.log('Age Errors:', errors.getByField('age')); //returns the errors for the age field