摘要:數據讀取器相當于原始數據格式與標準數據格式之間的橋梁,它屏蔽了原始數據格式不同對程序開發造成的影響。零是有效的,但空字符串無效。
用了Extjs快一年了,這里整理一下model。
數據模型Extjs 中數據包總共包含了40多個類,其中有三個類比其他類有更重要的地位,它們分別是:model、store和proxy,這些類在大部分的應用系統中都會用到并且得到了大量衛星類的支持,如上圖。數據包的中心是Ext.data.Model,一個model代表系統中的一些數據的類型,比如:我們的成果管理系統中的論文、專利、獎勵的model。它是真實世界中實體對象在應用系統中的反映。
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"} ]
});
這是一個最簡單的model,只有fields,接下來我們還會講到model的四個主要的部分--Fields,Proxy,Association 和 Validations。
通常,model和store一起使用,如果說model是數據的類型,它的實例是一條數據記錄,那么store實例是model實例的集合,創建一個store并且加載數據。
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配置了一個Ajax Proxy(后面講),告訴他URL,讓它從這個地方獲取數據,還配了reader去解析數據(reader后面也講),服務器返回Json,所以我們創建了一個Json reader 去讀取響應(response)。Store自動加載一組model 實例,就像這樣
Store還提供了對數據的過濾、排序、分組的功能:
Ext.define("Srims.store.patent.patents", { extend: "Ext.data.Store", model: "Srims.model.patent.patents", //…… sorters: ["Title", "id"]; filters: { property: "DepartmentName", value: "信息科學與工程學院" } groupField: "status", groupDir: "Desc" });
在這個store中,我們將數據先按名稱排序,再按Id排序;然后過濾為只有學院為信息科學與工程學院的記錄,另外,根據記錄狀態按照降序分組。
因為store API中有很多有關的方法,可以根據需要隨時更改store的排序、過濾、分組方式。比如,在成果管理系統中,所屬項目列表,我要將列表中狀態為添加(A)和刪除(D)的記錄拿出來,就可以使用filter。
//給store添加過濾器 store.filter([ function(item) { return (item.data.Status == "A") || (item.data.Status == "D"); } ]); …… //清除過濾器 store().clearFilter();
一定要注意,一定要在結束后加上這句store().clearFilter(); 將該過濾器清除,不然之后store中就只有這些過濾后的數據。
上圖清晰地展示了model的4個重要組成部分。(字段定義、數據代理、模型關聯、數據校驗)。
proxyProxy被用來對model數據的讀取和保存的,有兩種proxy:客戶端proxy(Ext.data.proxy.Client)和服務器端proxy(Ext.data.proxy.Server),它們都繼承自Ext.data.proxy.Proxy類。
Ext.data.proxy.Client是在客戶端進行數據存取操作的基類,通常不會進行實例化,而是使用它的子類。Ext.data.proxy.Memory使用內存變量存取數據:Ext.data.proxy.LocalStorage和Ext.data.proxy.SessionStorage是Ext.data.proxy.WebStorage使用HTML5的新特性DOM Storage機制,用于存儲鍵值對。SessionStorage用于存儲與當前瀏覽器窗口關聯的數據,窗口關閉后,sessionStorage中存儲的數據將無法使用;localStorage用于長期存儲數據,窗口關閉后,localStorage中的數據仍然可以被訪問,所有瀏覽器窗口可以共享localStorage的數據。
Ext.data.proxy.Server是服務器端代理的父類,一般也不進行實例化。與客戶端代理不同,服務器代理會訪問遠程的服務器資源,適合于長期保存重要的數據資料。
Ext.data.proxy.AjaxExt.data.proxy.Ajax代理是一個在應用程序中使用最廣泛的服務器端代理(也是成果管理系統中主要使用的代理),它采用Ajax方式通過請求指定的URL來讀寫數據,他不能讀取跨域數據(Ext.data.proxy.JsonP主要用于跨域讀取數據)。
成果系統中當時因為index.html文件在本地,要請求214服務器上的數據,產生了跨域問題,后來把index文件頁放在214上,請求同在214上的數據,避免了跨域問題。
Ajax代理發起請求是會自動插入sorting排序、filtering過濾、paging分頁和grouping分組設置到每一個請求中,在成果系統中,在store中這樣配置,完成分頁:
Ext.define("Srims.store.achievementAudit.auditPatentList", { extend: "Ext.data.Store", model: "Srims.model.patent.patents", pageSize : 40, //分頁-每頁記錄數 proxy: { type: "ajax", url: Srims.api.patentlist + "2", reader: { totalProperty: ‘TotalRecordCount’, //獲取接收到的數據的記錄總數 type: "json", root: "DataList", successProperty: "success" } }, autoLoad: true });
數據讀取器主要用于將數據代理讀取到的原始數據按照不同的規則進行解析,將解析后的數據保存在Model模型對象中。數據讀取器相當于原始數據格式與Extjs標準數據格式之間的橋梁,它屏蔽了原始數據格式不同對程序開發造成的影響。在Extjs中提供的數據解析器主要有如下3種:
Ext.data.reader.Json (JSON數據讀取器)
Ext.data.reader.Xml (XML數據讀取器)
Ext.data.reader.Array (數組數據讀取器)
reader: { type: "json", root: "DataList", //返回信息的屬性名 totalProperty: "TotalRecordCount", //獲取記錄總數的屬性名 }writer數據寫入器
數據寫入器主要用于將數據代理提交到服務器的數據進行編碼,相當于Extjs標準數據格式與服務器數據格式之間的橋梁,他屏蔽了服務器端數據格式不同對程序開發造成的影響。在Extjs中提供的數據寫入器有:
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是一個特殊化的Ajax代理,將四種動作(create,read,update和destroy)映射到四種restful http動詞(put,get,post和delete)上,將請求的URL轉化為rest風格,方便進行rest風格的web應用開發。
rest代理會根據前端框架情況,判斷要執行的操作,從而判斷用什么方法及需要訪問的資源,最終確定URL。比如,在調用save方法時,會自動判斷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 //擴展save,添加回調函數 user.save({ success: function(user) { user.set("name", "Khan Noonien Singh"); user.save(); //PUT /users/123 } }); user.destroy(); //DELETE /users/123association
在應用系統中總會有不同的模型,這些模型之間大部分情況下是有關聯的,比如,成果系統中,論文和作者、專利和發明人、獎勵和獲獎人之間存在一對多的關系,在Extjs4中支持的關聯關系包括一對多和多對一兩種,分別通過Ext.data.HasManyAssociation類和Ext.data.BelongsToAssociation類實現。
這是官網上的一個例子:
//用戶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" });
關于讀數據
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了相關的post和comment。
每一個我們創建的hasMany關系就會有個新的方法添加到這個model。根據name生get方法,不然自動生成默認的model名字小寫加s,user.posts(),調用該方法,會返回一個配有post model的store,同樣,post獲得了一個comments()方法。
數據大概是這個樣子的:
{ 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.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聯系不僅能幫助我們讀數據,它對創建新的記錄也有幫助(代碼)我們創建了一條新的帖子,給了當前user的Id為user_Id的記錄。調用sync()方法通過配置好的proxy保存新的記錄,這是異步的操作,我如我們想在操作成功后做其他操作可以在里面添加回調函數。
結合前兩部分的一個例子一個專利對應多個發明人。
//專利詳細信息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: {/*??*/} }); //發明人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中都需要參數,那么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);
有關發明人的URL中間某個位置需要參數……
添加一條發明人記錄:
POST http://222.195.150.214:24367/api/patents/{patentId}/patentInventors
修改一條發明人記錄:
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); } } });
讀寫發明人:
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 確保了一個string類型的字段長度必須在最大值和最小值之間,兩個值都是可選的。
format 確保字符串必須與正則表達式匹配。
inclusion 確保該字段的值必須在一個特定的集合中。
exclusion 與inclusion相反,確保該字段的值不在某個特定的集合中。
-
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: ... });
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/90854.html
摘要:接著來,上一篇搭建了基本的項目骨架,到最后,其實啥也沒看見。。。目標全屏顯示左側導航菜單,右側標簽頁切換操作內容區域。一般模型與你后臺返回的數據結構一一對應。給其他組件提供一致接口使用數據。整個構成一個所謂的。 接著來,上一篇搭建了基本的項目骨架,到最后,其實啥也沒看見。。。書接上回,開始寫UI效果。 目標 全屏顯示、左側導航菜單,右側標簽頁切換操作內容區域。包含header和foo...
摘要:根據模塊創建模塊失敗。在中,我們配置了標明了這是一個控制器模塊,點擊后會去觸發控制器加載動作。正常情況下同一個模塊的只加載一次。 前面幾篇文檔,我們基本實現了一個靜態的extjs頁面,本篇開始,實現左側導航樹與右側內容的聯動,也就是點擊導航菜單,加載對應模塊頁面和業務邏輯,實現js文件的按需加載。 業務需求是這樣的: 左側的treelist,當點擊某個節點的時候,系統根據tree數據里...
摘要:而且上一篇文章中,也已經實現了一個基本的用戶管理列表頁面。接著上一篇,完善用戶管理,實現增刪改。為了用戶體驗,增加和修改用戶信息的表單,都放在彈窗中進行。 經過前面幾篇文章的介紹,一個基本的MVC結構應該是具備了。而且上一篇文章中,也已經實現了一個基本的用戶管理列表頁面。接著上一篇,完善用戶管理,實現增刪改。為了用戶體驗,增加和修改用戶信息的表單,都放在彈窗中進行。避免跳轉頁面。 定義...
摘要:今天開始,一點點記錄一下使用搭建一個基礎結構的過程。沒辦法,記性差這種結構的前端,主要是面向后臺信息管理系統,可以最大限度的規范前端代碼結構和數據結構。 今天開始,一點點記錄一下使用extjs6.2.0搭建一個基礎MVC結構的過程。沒辦法,記性差:)這種結構的UI前端,主要是面向后臺信息管理系統,可以最大限度的規范前端代碼結構和數據結構。做網站 或者手機端,這種方式全引入了extjs,...
閱讀 3656·2021-10-09 09:58
閱讀 1199·2021-09-22 15:20
閱讀 2501·2019-08-30 15:54
閱讀 3516·2019-08-30 14:08
閱讀 891·2019-08-30 13:06
閱讀 1823·2019-08-26 12:16
閱讀 2685·2019-08-26 12:11
閱讀 2514·2019-08-26 10:38