Sencha ExtJS5.x 的數(shù)據(jù)包Data Package講解

數(shù)據(jù)包是你應(yīng)用程序加載和保存所有數(shù)據(jù)的地方踱讨。它包含大量的類檐涝,其中有三個(gè)比其它所有的都更重要异逐。

它們是: Ext.data.Model / Store /Ext.data.proxy.Proxy

這三個(gè)類幾乎被所有的應(yīng)用程序使用飒焦,并且得到了許多周圍類來支持典奉。


data package

Models模型

數(shù)據(jù)包的核心就是Ext.data.Model.一個(gè)模型就在應(yīng)用程序中代表了一個(gè)實(shí)體,舉個(gè)例子榨呆,一個(gè)電子商務(wù)應(yīng)用程序可能需要有用戶罗标、商品和訂單,最基本的層次上來說积蜻,一個(gè)模型就定義了一系列的字段和其相關(guān)聯(lián)的業(yè)務(wù)邏輯闯割。

我們可以看一下模型的幾個(gè)主要部分:

Fields/ Proxies/ Validations/Associations


模型組成

創(chuàng)建一個(gè)模型

通常來說,使用一個(gè)基類來定義你的模型是一個(gè)好的選擇竿拆。這個(gè)基類可以方便你在一個(gè)地方對你的模型進(jìn)行特定的配置宙拉,這樣也方便配置schema,schema是你應(yīng)用程序所有模型的管理器丙笋,現(xiàn)在我們可以先重點(diǎn)關(guān)注下兩個(gè)比較有用的配置選項(xiàng):

Ext.define('MyApp.model.Base',{

??? extend: 'Ext.data.Model',


??? fields: [{

??????? name: 'id',

??????? type: 'int'

??? }],


??? schema: {

??????? namespace: 'MyApp.model',? // generate auto entityName


??????? proxy: {???? // Ext.util.ObjectTemplate

??????????? type: 'ajax',

??????????? url: '{entityName}.json',

??????????? reader: {

??????????????? type: 'json',

??????????????? rootProperty:'{entityName:lowercase}'

??????????? }

??????? }

??? }

});

不同的應(yīng)用程序在基類模型中會有不同的內(nèi)容谢澈,尤其是fields.

Proxies代理

代理是在Models和Stores中使用的煌贴,它負(fù)責(zé)加載和保存模型的數(shù)據(jù)。有兩種不同類型的代理:客戶端和服務(wù)端(Client And Server).

代理可以直接在基類model的schema中定義锥忿,比如上面的代碼例子牛郑。

客戶端代理

客戶端的例子有Memory和Local

Storage,使用了HTML5的localstorage特性敬鬓。盡管舊的瀏覽器不支持這些新的HTML5 AP淹朋,但是它在實(shí)際應(yīng)用中是非常有用的。

服務(wù)端代理

服務(wù)端代理負(fù)責(zé)封裝遠(yuǎn)程服務(wù)的數(shù)據(jù)钉答,例子有AJAX/JSONP/REST础芍。

Schema

Schema是一系列有彼此關(guān)聯(lián)的實(shí)體。當(dāng)一個(gè)模型配置了schema,所有的衍生類都會繼承数尿。上述例子中仑性,schema已經(jīng)默認(rèn)給所有的模型配置了兩個(gè)默認(rèn)屬性。

第一個(gè)配置是namespace命名空間右蹦,通過指定這個(gè)命名空間诊杆,所有實(shí)體都擁有了一個(gè)縮略名,縮略名在定義實(shí)體關(guān)聯(lián)關(guān)系的時(shí)候非常重要嫩实。

第二個(gè)配置是 代理proxy刽辙,這是一個(gè)類模板窥岩,跟Ext.XTemplete有點(diǎn)類似甲献。不同的就是類模板在給定數(shù)據(jù)的時(shí)候產(chǎn)生的是對象,在此指定之后颂翼,沒有顯示指定proxy的都會使用該proxy.

應(yīng)用程序中很可能會存在這種微小差異但又絕大多數(shù)相同的請求晃洒,通過這樣配置,可以減少每個(gè)模型直接的重復(fù)定義proxy朦乏。

User.json被我們指定為url:{entityName.json}球及,應(yīng)該返回JSON字符串。在例子中我們使用的是

{

? "success": "true",

? "user": [

??? {

????? "id": 1,

????? "name": "Philip J.Fry"

??? },

??? {

????? "id": 2,

????? "name": "HubertFarnsworth"

??? },

??? {

????? "id": 3,

????? "name": "TurangaLeela"

??? },

??? {

????? "id": 4,

????? "name": "Amy Wong"

??? }

? ]

}

Stores

通常情況下model模型會配合store一起使用呻疹,store是一系列的records記錄的集合吃引,而record是一個(gè)模型驅(qū)動的類的實(shí)例,下面的例子是一個(gè)創(chuàng)建store和加載數(shù)據(jù)的:

var store = new Ext.data.Store({

??? model: 'MyApp.model.User'

});


store.load({

??? callback:function(){

??????? var first_name =this.first().get('name');

???????? console.log(first_name);

??? }

});

我們手動加載store來獲取一系列的MyApp.model.User的記錄刽锤,這些記錄在加載完成后會在回調(diào)事件中打印出來镊尺。

內(nèi)聯(lián)數(shù)據(jù)Inline data

Store可以加載內(nèi)聯(lián)數(shù)據(jù),store根據(jù)我們傳入的對象加載到模型適合的類型中去并思。

new Ext.data.Store({

??? model: 'MyApp.model.User',

??? data: [{

??????? id: 1,

??????? name: "Philip J. Fry"

??? },{

??????? id: 2,

??????? name: "Hubert Farnsworth"

??? },{

??????? id: 3,

??????? name: "Turanga Leela"

??? },{

??????? id: 4,

??????? name: "Amy Wong"

??? }]

});

排序和分組

Stores可以執(zhí)行排序庐氮,分組和過濾,可以是本地的也可以是服務(wù)端的宋彼。

new Ext.data.Store({

??? model: 'MyApp.model.User',


??? sorters: ['name','id'],

??? filters: {

??????? property: 'name',

??????? value??: 'Philip J. Fry'

??? }

});

在這個(gè)store中弄砍,數(shù)據(jù)通過name和id排序仙畦,數(shù)據(jù)會過濾只加載包含Philip J. Fry的用戶,通過API可以隨時(shí)對這些屬性進(jìn)行調(diào)整修改音婶。

Associations關(guān)聯(lián)關(guān)系

模型可以通過關(guān)聯(lián)關(guān)系A(chǔ)PI聚合到一起慨畸,多數(shù)應(yīng)用程序會處理很多模型,并且模型直接存在關(guān)系衣式。一個(gè)授權(quán)博客程序可能會有用戶和發(fā)稿先口,每一個(gè)用戶創(chuàng)建很多稿件,所以一個(gè)用戶可能會存在多個(gè)發(fā)稿瞳收,但是一個(gè)稿件只能被一個(gè)用戶發(fā)布碉京,這就是大家熟知的多對一關(guān)系,我們在ExtJS中這樣表達(dá):

Ext.define('MyApp.model.User',{

??? extend: 'MyApp.model.Base',


??? fields: [{

??????? name: 'name',

??????? type: 'string'

??? }]

});


Ext.define('MyApp.model.Post',{

??? extend: 'MyApp.model.Base',


??? fields: [{

??????? name: 'userId',

??????? reference: 'User', // the entityNamefor MyApp.model.User

??????? type: 'int'

??? }, {

??????? name: 'title',

??????? type: 'string'

??? }]

});

在應(yīng)用程序中對豐富的關(guān)系模型進(jìn)行表述可以說是很方便了螟深。每一個(gè)模型都可以有任意數(shù)量的對其他模型的關(guān)聯(lián)關(guān)系谐宙。另外,你的模型定義的順序也可以比較隨意界弧,一旦你有了這個(gè)模型的類型凡蜻,你就可以方便的遍歷關(guān)聯(lián)數(shù)據(jù)了。比如垢箕,你想獲取一個(gè)用戶所有的發(fā)稿划栓,你就可以這樣做:

// Loads User with ID 1 andrelated posts and comments

// using User's Proxy

MyApp.model.User.load(1, {

??? callback: function(user) {

??????? console.log('User: ' +user.get('name'));


??????? user.posts(function(posts){

??????????? posts.each(function(post) {

??????????????? console.log('Post: ' +post.get('title'));

??????????? });

??????? });

??? }

});

上述代碼是說,model新增了一個(gè)方法user.posts()条获,每一個(gè)用戶都有許多發(fā)稿忠荞,調(diào)用user.posts()就會返回Post模型配置的store。

關(guān)聯(lián)關(guān)系不僅在加載數(shù)據(jù)的時(shí)候有用帅掘,在創(chuàng)建新的記錄的時(shí)候也可以用:

user.posts().add({

??? userId: 1,

??? title: 'Post 10'

});


user.posts().sync();

這個(gè)實(shí)例創(chuàng)建了一個(gè)新的發(fā)稿委煤,自動賦值用戶ID給ID字段,調(diào)用sync()方法通過proxy保存新的發(fā)稿修档,這是異步的方法碧绞,所以你可以設(shè)置當(dāng)完成操作的時(shí)候進(jìn)行回調(diào)。

逆關(guān)聯(lián)關(guān)系在Post模型中也會產(chǎn)生新的方法:

MyApp.model.Post.load(1, {

??? callback: function(post) {


??????? post.getUser(function(user) {

??????????? console.log('Got user from post: '+ user.get('name'));

??????? });??????????????????????????

??? }

});


MyApp.model.Post.load(2, {

??? callback: function(post) {

??????? post.setUser(100);????????????????????????

??? }

});

加載方法getUser()是異步的吱窝,需要一個(gè)回調(diào)來創(chuàng)建用戶實(shí)例讥邻,setUser()方法僅僅就是更新了用戶id為100并且保存了Post模型,跟以前一樣院峡,可以通過保存操作的返回成功與否觸發(fā)回調(diào)兴使。

加載嵌入數(shù)據(jù)

當(dāng)關(guān)聯(lián)關(guān)系定義好之后,單請求可以同時(shí)請求到關(guān)聯(lián)數(shù)據(jù)撕予,比如鲫惶,看下面的返回值;{

??? "success": true,

??? "user": [{

??????? "id": 1,

??????? "name": "Philip J.Fry",

??????? "posts": [{

??????????? "title": "Post1"

??????? },{

??????????? "title": "Post2"

??????? },{

??????????? "title": "Post3"

??????? }]

??? }]

}

通過單請求实抡,可以同時(shí)獲取用戶和用戶下的文章欠母,兒不必先請求用戶欢策,再根據(jù)用戶獲取下面的發(fā)稿。

驗(yàn)證

模型同時(shí)也提供了對數(shù)據(jù)校驗(yàn)的一大群支持赏淌,為了進(jìn)行演示踩寇,我們通過上述例子進(jìn)行構(gòu)造數(shù)據(jù),我們給用戶模型增加了一些數(shù)據(jù)校驗(yàn):

Ext.define('MyApp.model.User',{

??? extend: 'Ext.data.Model',

??? fields: ...,


??? validators: {

??????? name: [

??????????? 'presence',

??????????? { type: 'length', min: 7 },

??????????? { type: 'exclusion', list: ['Bender']}

??????? ]

??? }

});

校驗(yàn)定義一個(gè)name字段六水,對該字段進(jìn)行校驗(yàn)俺孙,校驗(yàn)規(guī)則就是name字段下配置的對象,例子說的是對name字段進(jìn)行校驗(yàn)掷贾,校驗(yàn)規(guī)則是長度不得少于7個(gè)字符睛榄,數(shù)據(jù)可以是除了Bender之外的任何數(shù)據(jù)。

有些嚴(yán)重包含其他一些配置選擇想帅,比如長度可以有最長和最短场靴,max min屬性,格式化可以使用matcher等港准,ExtJS提供了五個(gè)校驗(yàn)旨剥,用戶自定義校驗(yàn)也很簡單:

Presence-確保該字段必須存在值,不允許有空字符串浅缸。

Length-確保字符串有正確的長度轨帜,最大最小都是可選的。

Format-確保字符串滿足正則表達(dá)式的格式衩椒。

Inclusion-確保值包含我們要求的蚌父。

Exclusion-確保值不包含我們要求的。

下面可以通過用戶實(shí)例來嘗試使用校驗(yàn)烟具,我們創(chuàng)建一個(gè)用戶梢什,進(jìn)行校驗(yàn)的:

// now lets try to create anew user with as many validation

// errors as we can

var newUser = newMyApp.model.User({

??? id: 10,

??? name: 'Bender'

});


// run some validation on thenew user we just created

console.log('Is User valid?',newUser.isValid());


//returns 'false' as therewere validation errors


var errors =newUser.getValidation(),

??? error?= errors.get('name');


console.log("Error is:" + error);

關(guān)鍵方法就是getValidation(),通過該方法進(jìn)行校驗(yàn)和返回校驗(yàn)結(jié)果朝聋,校驗(yàn)記錄是懶加載的并且需要的時(shí)候才更新。

上面的結(jié)果是:Length must be greater than 7

所以我們提供一個(gè)大于7個(gè)字符的字符:

newUser.set('name', 'BenderBending Rodriguez');

errors =newUser.getValidation();

這樣囤躁,所有條件都被滿足了冀痕,調(diào)用newUser.isValid()返回true,當(dāng)我們調(diào)用getValidation()就能保證字段都是正常的了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末狸演,一起剝皮案震驚了整個(gè)濱河市言蛇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宵距,老刑警劉巖腊尚,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異满哪,居然都是意外死亡婿斥,警方通過查閱死者的電腦和手機(jī)劝篷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來民宿,“玉大人娇妓,你說我怎么就攤上這事』钣ィ” “怎么了哈恰?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長志群。 經(jīng)常有香客問我着绷,道長,這世上最難降的妖魔是什么锌云? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任蓬戚,我火速辦了婚禮,結(jié)果婚禮上宾抓,老公的妹妹穿的比我還像新娘子漩。我一直安慰自己石洗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布讲衫。 她就那樣靜靜地躺著缕棵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪涉兽。 梳的紋絲不亂的頭發(fā)上招驴,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機(jī)與錄音枷畏,去河邊找鬼别厘。 笑死,一個(gè)胖子當(dāng)著我的面吹牛拥诡,可吹牛的內(nèi)容都是我干的触趴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼渴肉,長吁一口氣:“原來是場噩夢啊……” “哼冗懦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起仇祭,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤披蕉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體没讲,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡眯娱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了食零。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片困乒。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖贰谣,靈堂內(nèi)的尸體忽然破棺而出娜搂,到底是詐尸還是另有隱情,我是刑警寧澤吱抚,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布百宇,位于F島的核電站,受9級特大地震影響秘豹,放射性物質(zhì)發(fā)生泄漏携御。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一既绕、第九天 我趴在偏房一處隱蔽的房頂上張望啄刹。 院中可真熱鬧,春花似錦凄贩、人聲如沸誓军。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽昵时。三九已至,卻和暖如春椒丧,著一層夾襖步出監(jiān)牢的瞬間壹甥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工句柠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留久橙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓淆衷,卻偏偏與公主長得像祝拯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子鹰贵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理碉输,服務(wù)發(fā)現(xiàn)亭珍,斷路器,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架肄梨,建立于...
    Hsinwong閱讀 22,403評論 1 92
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,934評論 2 89
  • 22年12月更新:個(gè)人網(wǎng)站關(guān)停侨赡,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,182評論 22 257
  • 你知道嗎油猫?今天是世界讀書日,也是莎士比亞的誕辰和祭日尔店。 為了紀(jì)念他,后人把4月23日定為世界讀書日鲫售,也是為了鼓勵和...
    后知后覺的人閱讀 354評論 0 6