摘要:數(shù)據(jù)讀取器相當(dāng)于原始數(shù)據(jù)格式與標(biāo)準(zhǔn)數(shù)據(jù)格式之間的橋梁,它屏蔽了原始數(shù)據(jù)格式不同對程序開發(fā)造成的影響。零是有效的,但空字符串無效。
用了Extjs快一年了,這里整理一下model。
數(shù)據(jù)模型Extjs 中數(shù)據(jù)包總共包含了40多個(gè)類,其中有三個(gè)類比其他類有更重要的地位,它們分別是:model、store和proxy,這些類在大部分的應(yīng)用系統(tǒng)中都會(huì)用到并且得到了大量衛(wèi)星類的支持,如上圖。數(shù)據(jù)包的中心是Ext.data.Model,一個(gè)model代表系統(tǒng)中的一些數(shù)據(jù)的類型,比如:我們的成果管理系統(tǒng)中的論文、專利、獎(jiǎng)勵(lì)的model。它是真實(shí)世界中實(shí)體對象在應(yīng)用系統(tǒng)中的反映。
model和store我們來看下在Ext中model代碼:
Ext.define("Srims.model.patent.patents", { extend: "Ext.data.Model", fields: [ { name: "id", type: "int", mapping: "Id"}, { name: "Title", type: "string", mapping: "Title"}, { name: "PatentNumber", type: "string", mapping: "PatentNumber"}, { name: "PatentType", type: "string", mapping: "PatentType"}, { name: "PatentStatus", type: "string"}, { name: "AuthorizeDateTime",type: "string", mapping: "AuthorizeDateTime"}, { name: "DepartmentId", type: "int"}, { name: "DepartmentName", type: "string", mapping: "DepartmentName"}, { name: "ResponsorName", type: "string", mapping: "ResponsorName"}, { name: "Status", type: "string"} ]
});
這是一個(gè)最簡單的model,只有fields,接下來我們還會(huì)講到model的四個(gè)主要的部分--Fields,Proxy,Association 和 Validations。
通常,model和store一起使用,如果說model是數(shù)據(jù)的類型,它的實(shí)例是一條數(shù)據(jù)記錄,那么store實(shí)例是model實(shí)例的集合,創(chuàng)建一個(gè)store并且加載數(shù)據(jù)。
Ext.define("Srims.store.patent.patents", { extend: "Ext.data.Store", model: "Srims.model.patent.patents", proxy: { type: "ajax", url:"http://222.195.150.214:24367/api/patents/getbystatus/1", reader: { type: "json", root: "DataList", successProperty: "success" } }, autoLoad: true });
我們給store配置了一個(gè)Ajax Proxy(后面講),告訴他URL,讓它從這個(gè)地方獲取數(shù)據(jù),還配了reader去解析數(shù)據(jù)(reader后面也講),服務(wù)器返回Json,所以我們創(chuàng)建了一個(gè)Json reader 去讀取響應(yīng)(response)。Store自動(dòng)加載一組model 實(shí)例,就像這樣
Store還提供了對數(shù)據(jù)的過濾、排序、分組的功能:
Ext.define("Srims.store.patent.patents", { extend: "Ext.data.Store", model: "Srims.model.patent.patents", //…… sorters: ["Title", "id"]; filters: { property: "DepartmentName", value: "信息科學(xué)與工程學(xué)院" } groupField: "status", groupDir: "Desc" });
在這個(gè)store中,我們將數(shù)據(jù)先按名稱排序,再按Id排序;然后過濾為只有學(xué)院為信息科學(xué)與工程學(xué)院的記錄,另外,根據(jù)記錄狀態(tài)按照降序分組。
因?yàn)閟tore API中有很多有關(guān)的方法,可以根據(jù)需要隨時(shí)更改store的排序、過濾、分組方式。比如,在成果管理系統(tǒng)中,所屬項(xiàng)目列表,我要將列表中狀態(tài)為添加(A)和刪除(D)的記錄拿出來,就可以使用filter。
//給store添加過濾器 store.filter([ function(item) { return (item.data.Status == "A") || (item.data.Status == "D"); } ]); …… //清除過濾器 store().clearFilter();
一定要注意,一定要在結(jié)束后加上這句store().clearFilter(); 將該過濾器清除,不然之后store中就只有這些過濾后的數(shù)據(jù)。
上圖清晰地展示了model的4個(gè)重要組成部分。(字段定義、數(shù)據(jù)代理、模型關(guān)聯(lián)、數(shù)據(jù)校驗(yàn))。
proxyProxy被用來對model數(shù)據(jù)的讀取和保存的,有兩種proxy:客戶端proxy(Ext.data.proxy.Client)和服務(wù)器端proxy(Ext.data.proxy.Server),它們都繼承自Ext.data.proxy.Proxy類。
Ext.data.proxy.Client是在客戶端進(jìn)行數(shù)據(jù)存取操作的基類,通常不會(huì)進(jìn)行實(shí)例化,而是使用它的子類。Ext.data.proxy.Memory使用內(nèi)存變量存取數(shù)據(jù):Ext.data.proxy.LocalStorage和Ext.data.proxy.SessionStorage是Ext.data.proxy.WebStorage使用HTML5的新特性DOM Storage機(jī)制,用于存儲鍵值對。SessionStorage用于存儲與當(dāng)前瀏覽器窗口關(guān)聯(lián)的數(shù)據(jù),窗口關(guān)閉后,sessionStorage中存儲的數(shù)據(jù)將無法使用;localStorage用于長期存儲數(shù)據(jù),窗口關(guān)閉后,localStorage中的數(shù)據(jù)仍然可以被訪問,所有瀏覽器窗口可以共享localStorage的數(shù)據(jù)。
Ext.data.proxy.Server是服務(wù)器端代理的父類,一般也不進(jìn)行實(shí)例化。與客戶端代理不同,服務(wù)器代理會(huì)訪問遠(yuǎn)程的服務(wù)器資源,適合于長期保存重要的數(shù)據(jù)資料。
Ext.data.proxy.AjaxExt.data.proxy.Ajax代理是一個(gè)在應(yīng)用程序中使用最廣泛的服務(wù)器端代理(也是成果管理系統(tǒng)中主要使用的代理),它采用Ajax方式通過請求指定的URL來讀寫數(shù)據(jù),他不能讀取跨域數(shù)據(jù)(Ext.data.proxy.JsonP主要用于跨域讀取數(shù)據(jù))。
成果系統(tǒng)中當(dāng)時(shí)因?yàn)閕ndex.html文件在本地,要請求214服務(wù)器上的數(shù)據(jù),產(chǎn)生了跨域問題,后來把index文件頁放在214上,請求同在214上的數(shù)據(jù),避免了跨域問題。
Ajax代理發(fā)起請求是會(huì)自動(dòng)插入sorting排序、filtering過濾、paging分頁和grouping分組設(shè)置到每一個(gè)請求中,在成果系統(tǒng)中,在store中這樣配置,完成分頁:
Ext.define("Srims.store.achievementAudit.auditPatentList", { extend: "Ext.data.Store", model: "Srims.model.patent.patents", pageSize : 40, //分頁-每頁記錄數(shù) proxy: { type: "ajax", url: Srims.api.patentlist + "2", reader: { totalProperty: ‘TotalRecordCount’, //獲取接收到的數(shù)據(jù)的記錄總數(shù) type: "json", root: "DataList", successProperty: "success" } }, autoLoad: true });
數(shù)據(jù)讀取器主要用于將數(shù)據(jù)代理讀取到的原始數(shù)據(jù)按照不同的規(guī)則進(jìn)行解析,將解析后的數(shù)據(jù)保存在Model模型對象中。數(shù)據(jù)讀取器相當(dāng)于原始數(shù)據(jù)格式與Extjs標(biāo)準(zhǔn)數(shù)據(jù)格式之間的橋梁,它屏蔽了原始數(shù)據(jù)格式不同對程序開發(fā)造成的影響。在Extjs中提供的數(shù)據(jù)解析器主要有如下3種:
Ext.data.reader.Json (JSON數(shù)據(jù)讀取器)
Ext.data.reader.Xml (XML數(shù)據(jù)讀取器)
Ext.data.reader.Array (數(shù)組數(shù)據(jù)讀取器)
reader: { type: "json", root: "DataList", //返回信息的屬性名 totalProperty: "TotalRecordCount", //獲取記錄總數(shù)的屬性名 }writer數(shù)據(jù)寫入器
數(shù)據(jù)寫入器主要用于將數(shù)據(jù)代理提交到服務(wù)器的數(shù)據(jù)進(jìn)行編碼,相當(dāng)于Extjs標(biāo)準(zhǔn)數(shù)據(jù)格式與服務(wù)器數(shù)據(jù)格式之間的橋梁,他屏蔽了服務(wù)器端數(shù)據(jù)格式不同對程序開發(fā)造成的影響。在Extjs中提供的數(shù)據(jù)寫入器有:
Ext.data.writer.Json (Json寫入器)
Ext.data.writer.Xml (xml寫入器)
--
Ext.define("User", { extend:"Ext.data.Model", fields:[ {name:"name", type:"string"}, {name:"age", type:"int"} ], proxy:{ type : "ajax", url : " fakeData.jsp", writer:{ type : "json" } } }); var user = Ext.ModelMgr.create({ name: "Tom", age: 24 } ,"User"); user.save();Ext.data.proxy.Rest
Ext.data.proxy.Rest是一個(gè)特殊化的Ajax代理,將四種動(dòng)作(create,read,update和destroy)映射到四種restful http動(dòng)詞(put,get,post和delete)上,將請求的URL轉(zhuǎn)化為rest風(fēng)格,方便進(jìn)行rest風(fēng)格的web應(yīng)用開發(fā)。
rest代理會(huì)根據(jù)前端框架情況,判斷要執(zhí)行的操作,從而判斷用什么方法及需要訪問的資源,最終確定URL。比如,在調(diào)用save方法時(shí),會(huì)自動(dòng)判斷Model的id屬性是否有值如果有就使用update路徑,如果沒有就使用create路徑:
Ext.define("User", { extend: "Ext.data.Model", fields: ["id", "name", "email"], proxy: { type: "rest", url : "/users" } }); var user = Ext.create("User", { name: "Ed Spencer", email: "ed@sencha.com" }); user.save(); //POST /users //擴(kuò)展save,添加回調(diào)函數(shù) user.save({ success: function(user) { user.set("name", "Khan Noonien Singh"); user.save(); //PUT /users/123 } }); user.destroy(); //DELETE /users/123association
在應(yīng)用系統(tǒng)中總會(huì)有不同的模型,這些模型之間大部分情況下是有關(guān)聯(lián)的,比如,成果系統(tǒng)中,論文和作者、專利和發(fā)明人、獎(jiǎng)勵(lì)和獲獎(jiǎng)人之間存在一對多的關(guān)系,在Extjs4中支持的關(guān)聯(lián)關(guān)系包括一對多和多對一兩種,分別通過Ext.data.HasManyAssociation類和Ext.data.BelongsToAssociation類實(shí)現(xiàn)。
這是官網(wǎng)上的一個(gè)例子:
//用戶model 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" } }); //帖子model 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: "Comment }); //評論model Ext.define("Comment", { extend: "Ext.data.Model", fields: ["id", "post_id", "name", "message‘ ], belongsTo: "Post" });
關(guān)于讀數(shù)據(jù)
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")); }); }); } });
load Id為1的user,并且通過user的proxy load了相關(guān)的post和comment。
每一個(gè)我們創(chuàng)建的hasMany關(guān)系就會(huì)有個(gè)新的方法添加到這個(gè)model。根據(jù)name生get方法,不然自動(dòng)生成默認(rèn)的model名字小寫加s,user.posts(),調(diào)用該方法,會(huì)返回一個(gè)配有post model的store,同樣,post獲得了一個(gè)comments()方法。
數(shù)據(jù)大概是這個(gè)樣子的:
{ 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" }] }] }] }
關(guān)于寫數(shù)據(jù)
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(); //通過配置好的proxy保存新的記錄
association聯(lián)系不僅能幫助我們讀數(shù)據(jù),它對創(chuàng)建新的記錄也有幫助(代碼)我們創(chuàng)建了一條新的帖子,給了當(dāng)前user的Id為user_Id的記錄。調(diào)用sync()方法通過配置好的proxy保存新的記錄,這是異步的操作,我如我們想在操作成功后做其他操作可以在里面添加回調(diào)函數(shù)。
結(jié)合前兩部分的一個(gè)例子一個(gè)專利對應(yīng)多個(gè)發(fā)明人。
//專利詳細(xì)信息model Ext.define("Srims.model.patent.patentDetail", { extend: "Ext.data.Model", fields: [ { name: "id", type: "int"} { name: "patentName", type: "string"}, { name: "patentNumber", type: "string"}, …… ], hasMany: { model: "Srims.model.patent.inventors", name: "Owners", associationKey: "Owners", foreignKey: "patentId" } proxy: {/*??*/} }); //發(fā)明人model Ext.define("Srims.model.patent.inventors", { extend: "Ext.data.Model", fields: [ { name: "Id", type: "int" }, { name: "Ordinal", type: "int" }, { name: "Name", type: "string" }, …… { name: "patentId", type: "int"} ] belongsTo: "Srims.model.patent.patents" proxy: {/*??*/} });
URL中都需要參數(shù),那么proxy如何配置?
Ext.define("Srims.model.patent.patentDetail", { …… proxy: { type: "rest", reader: {type: "json"}, url: "http://222.195.150.214:24367/api/patents" } }); var patentModel = Ext.ModelManager.getModel("Srims.model.patent.patentDetail"); patentModel.load(3017);
有關(guān)發(fā)明人的URL中間某個(gè)位置需要參數(shù)……
添加一條發(fā)明人記錄:
POST http://222.195.150.214:24367/api/patents/{patentId}/patentInventors
修改一條發(fā)明人記錄:
PUT http://222.195.150.214:24367/api/patents/{patentId/patentInventors/{ordinal}
Ext.define("Srims.model.patent.inventors", { extend: "Ext.data.Model", …… proxy: { type: "rest", reader: {type: "json"}, url: "http://222.195.150.214:24367/api/patents/{}/patentInventors", //重寫buildUrl buildUrl: function(request) { var me = this, operation = request.operation, records = operation.records || [], record = records[0], url = me.getUrl(request), id = record && record.get("patentId"); Ordinal = record && record.get("Ordinal"); if (me.isValidId(id)) { //將{}替換為patentId url = url.replace("{}", id); } else { throw new Error("A valid id is required"); } if (operation.action === “update”) { //若為修改操作,在URL末尾加上位次 url += "/" + Ordinal; } request.url = url; return Ext.data.proxy.Rest.superclass.buildUrl.apply(this, arguments); } } });
讀寫發(fā)明人:
var patentModel = Ext.ModelManager.getModel("Srims.model.patent.patentDetail"); patentModel.load(3017, { success: function (record) { record.Owners().add({ Ordinal: 6, Name: "zhanglu" }); record.Owners().getNewRecords()[0].save({ //添加一條記錄 post success: function(){ record.Owners().sync(); //將其他記錄同步(equal to修改)put } }); } });validation
presence 保證了字段有值。零是有效的,但空字符串無效。
length 確保了一個(gè)string類型的字段長度必須在最大值和最小值之間,兩個(gè)值都是可選的。
format 確保字符串必須與正則表達(dá)式匹配。
inclusion 確保該字段的值必須在一個(gè)特定的集合中。
exclusion 與inclusion相反,確保該字段的值不在某個(gè)特定的集合中。
-
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: ... });
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/90854.html
摘要:接著來,上一篇搭建了基本的項(xiàng)目骨架,到最后,其實(shí)啥也沒看見。。。目標(biāo)全屏顯示左側(cè)導(dǎo)航菜單,右側(cè)標(biāo)簽頁切換操作內(nèi)容區(qū)域。一般模型與你后臺返回的數(shù)據(jù)結(jié)構(gòu)一一對應(yīng)。給其他組件提供一致接口使用數(shù)據(jù)。整個(gè)構(gòu)成一個(gè)所謂的。 接著來,上一篇搭建了基本的項(xiàng)目骨架,到最后,其實(shí)啥也沒看見。。。書接上回,開始寫UI效果。 目標(biāo) 全屏顯示、左側(cè)導(dǎo)航菜單,右側(cè)標(biāo)簽頁切換操作內(nèi)容區(qū)域。包含header和foo...
摘要:根據(jù)模塊創(chuàng)建模塊失敗。在中,我們配置了標(biāo)明了這是一個(gè)控制器模塊,點(diǎn)擊后會(huì)去觸發(fā)控制器加載動(dòng)作。正常情況下同一個(gè)模塊的只加載一次。 前面幾篇文檔,我們基本實(shí)現(xiàn)了一個(gè)靜態(tài)的extjs頁面,本篇開始,實(shí)現(xiàn)左側(cè)導(dǎo)航樹與右側(cè)內(nèi)容的聯(lián)動(dòng),也就是點(diǎn)擊導(dǎo)航菜單,加載對應(yīng)模塊頁面和業(yè)務(wù)邏輯,實(shí)現(xiàn)js文件的按需加載。 業(yè)務(wù)需求是這樣的: 左側(cè)的treelist,當(dāng)點(diǎn)擊某個(gè)節(jié)點(diǎn)的時(shí)候,系統(tǒng)根據(jù)tree數(shù)據(jù)里...
摘要:而且上一篇文章中,也已經(jīng)實(shí)現(xiàn)了一個(gè)基本的用戶管理列表頁面。接著上一篇,完善用戶管理,實(shí)現(xiàn)增刪改。為了用戶體驗(yàn),增加和修改用戶信息的表單,都放在彈窗中進(jìn)行。 經(jīng)過前面幾篇文章的介紹,一個(gè)基本的MVC結(jié)構(gòu)應(yīng)該是具備了。而且上一篇文章中,也已經(jīng)實(shí)現(xiàn)了一個(gè)基本的用戶管理列表頁面。接著上一篇,完善用戶管理,實(shí)現(xiàn)增刪改。為了用戶體驗(yàn),增加和修改用戶信息的表單,都放在彈窗中進(jìn)行。避免跳轉(zhuǎn)頁面。 定義...
摘要:前言本文章為平時(shí)工作是遇到的一些特效,不定時(shí)更新,并非完全原創(chuàng),如有意見或建議,請?jiān)谙路搅粞裕視?huì)做出相應(yīng)補(bǔ)充或處理。自適應(yīng)寬度復(fù)制按鈕實(shí)現(xiàn)通過點(diǎn)擊按鈕將特定內(nèi)容復(fù)制到瀏覽器剪貼板的功能。 前言 本文章為平時(shí)工作是遇到的一些Extjs特效,不定時(shí)更新,并非完全原創(chuàng),如有意見或建議,請?jiān)谙路搅粞裕視?huì)做出相應(yīng)補(bǔ)充或處理。 grid 鼠標(biāo)懸浮提示 通過列的render屬性改變樣式 func...
摘要:今天開始,一點(diǎn)點(diǎn)記錄一下使用搭建一個(gè)基礎(chǔ)結(jié)構(gòu)的過程。沒辦法,記性差這種結(jié)構(gòu)的前端,主要是面向后臺信息管理系統(tǒng),可以最大限度的規(guī)范前端代碼結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu)。 今天開始,一點(diǎn)點(diǎn)記錄一下使用extjs6.2.0搭建一個(gè)基礎(chǔ)MVC結(jié)構(gòu)的過程。沒辦法,記性差:)這種結(jié)構(gòu)的UI前端,主要是面向后臺信息管理系統(tǒng),可以最大限度的規(guī)范前端代碼結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu)。做網(wǎng)站 或者手機(jī)端,這種方式全引入了extjs,...
閱讀 3648·2021-10-09 09:58
閱讀 1188·2021-09-22 15:20
閱讀 2495·2019-08-30 15:54
閱讀 3509·2019-08-30 14:08
閱讀 887·2019-08-30 13:06
閱讀 1817·2019-08-26 12:16
閱讀 2678·2019-08-26 12:11
閱讀 2507·2019-08-26 10:38