數據記錄 Record 數據集合中的一個條記錄,包括數據的定義和值。相當于實體類。 數據代理 Proxy 用來獲取數據的代理。相當于Datasource。 數據解析器 DataReader 負責將Proxy獲取的 " /> 成年男女免费视频,国产无遮挡裸体免费视频在线观看 ,国产成人a毛片

一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

Extjs學習筆記之九 數據模型(上)

Extjs的數據模型分為以下幾個部分:

數據記錄 Record
數據集合中的一個條記錄,包括數據的定義和值。相當于實體類。
數據代理 Proxy
用來獲取數據的代理。相當于Datasource。
數據解析器 DataReader
負責將Proxy獲取的數據解析出來傳換成Record并存入Store中。相當于C#的DataReader。
數據集 Store
一個保存數據的集合,類似于C#的Datatable。
Extjs3的Proxy較以前版本有了一些變動,資料很少,而且官方文檔上相當簡練,以至于一個完整的例子都沒有…… 我盡力理解……

1. 數據記錄
一條數據記錄一般是有多個字段組成的。字段由Ext.data.Field類定義。Field的配置項很豐富,使我們有足夠的信息在弱類型的語言中處理我們的數據,主要有:

name:字段名;defaultValue:默認值;type:數據類型,可以是string,int,float,boolean,date和auto(默認)。先介紹這么多,其余的在具體用到的時候再介紹。

要建立一個數據記錄類(注意不是具體一條數據),可以使用Ext.data.Record.create方法,這個方法接受一個數組的Field類的配置項,返回一個構造函數。看一個例子:
復制代碼 代碼如下:
<script type="text/Javascript">
// create a Record constructor from a description of the fields
var TopicRecord = Ext.data.Record.create([ // creates a subclass of Ext.data.Record
{name: 'title' },
{ name: 'author', allowBlank: false },
{ name: 'totalPosts', type: 'int' },
{ name: 'lastPost',type: 'date' },
// In the simplest case, if no properties other than name are required,
// a field definition may consist of just a String for the field name.
'signature'
]);

// create Record instance
var myNewRecord = new TopicRecord(
{
title: 'Do my job please',
author: 'noobie',
totalPosts: 1,
lastPost: new Date(),
signature: ''
},
id // optionally specify the id of the record otherwise one is auto-assigned
);
alert(myNewRecord.get('author'));
</script>

這里演示的僅僅是Record最基本的功能:定義字段和存取數據。Record還可以和Store一起,由Store跟蹤Record的變化情況。就如C#的DataTable一樣,可以跟蹤其內部的DataRow變更的情況。Extjs幾乎把前臺開發變成了后臺。這些內容等介紹Store的時候再介紹。

2.數據代理
Ext.data.DataProxy是數據代理的抽象基類,實現了DataProxy的通用公共接口。DataProxy的最重要的通用方法就是doRequest,執行這個方法之后將從各種具體的數據源讀取數據。繼承自DataProxy的具體Proxy類有:

2.1 HttpProxy

這是最常用的proxy,通過一個http請求從遠程服務器獲取數據。HttpProxy最重要的配置項就是配置獲取數據的url。HttpProxy不僅僅支持獲取數據,它支持對數據的CRUD操作。DataProxy的api屬性就是用來配置這4種操作對應的url的。如果不配置,就采用HttpProxy的url屬性。例如:
復制代碼 代碼如下:
api: {
read: '/controller/load',
create : '/controller/new', // Server MUST return idProperty of new record

save : '/controller/update',
destroy : '/controller/destroy_action'
}

注意,extjs的官方文檔這里相當含糊不清:

四個操作中的第一個到底是read還是load???
配置好api后,就可以執行doRequest方法,doRequest方法的參數比較復雜:

doRequest( String action, Ext.data.Record/Ext.data.Record[] rs, Object params, Ext.data.DataReader reader, Function callback, Object scope, Object arg )含義如下:action:表示執行的是哪種操作,可以是 create,read,update,destroy的一種。rs: 看了半天也沒發現這個參數有什么用…… 看源代碼發現其中出現了這樣的表達式 url+rs.id,這個或許是為MVC架構的程序更好的構建url用的?直接忽略它,設為null即可。params:這個對象里邊的屬性:值對會作為post/get的參數傳到服務器,非常有用。

reader: DataReader,將服務器返回的數據解析成Record的數組。下面會有更詳細的解釋。

callback:當讀取到服務器數據之后執行的函數。這個函數接受三個參數,分別是: r Ext.Record[],服務器端返回的經過reader的數組。這是官方的說法,實際測試下來似乎只有當action是read的時候才是這樣,下面有介紹;options:就是arg參數的值。success:是否成功的標致,bool,這個也是服務器端返回的。

scope:作用域

arg:一些附加的參數,會被傳到callback的options參數中。

下面我們來完成一個例子,利用httpproxy完成基本的CRUD操作。先看服務器端代碼:
復制代碼 代碼如下:
<%@ WebHandler Language="C#" Class="dataproxy" %>

using System;
using System.Web;
using System.Collections.Generic;

public class dataproxy : IHttpHandler {
static List<Student> db = new List<Student>();
static dataproxy()
{
db.Add(new Student { Id = "1", Name = "Li", Telephone = "1232" });
db.Add(new Student { Id = "2", Name = "Wang", Telephone = "5568" });
db.Add(new Student { Id = "3", Name = "Chen", Telephone = "23516" });
db.Add(new Student { Id = "4", Name = "Zhu", Telephone = "45134" });
db.Add(new Student { Id = "5", Name = "Zhou", Telephone = "3455" });
}
public void ProcessRequest (HttpContext context) {
string id = context.Request.Params["id"];
string action=context.Request.Params["action"];
string result = "{success:false}";
if (action == "create")
{
}
else if (action == "read")
{
foreach (Student stu in db)
{
if (stu.Id == id)
{
result = "{success:true,r:[['" + stu.Id + "','" + stu.Name + "','" + stu.Telephone + "']]}";
break;
}
}
}
else if (action == "update")
{
}
else if (action == "delete")
{
}
context.Response.ContentType = "text/plain";
context.Response.Write(result);
}

public bool IsReusable {
get {
return false;
}
}

class Student
{
string id;
public string Id
{
get { return id; }
set { id = value; }
}
string name;
public string Name
{
get { return name; }
set { name = value; }
}
string telephone;

public string Telephone
{
get { return telephone; }
set { telephone = value; }
}
}
}

我們用一個靜態的List來模仿數據庫。在處理函數中分別應對4種情況。上面僅實現了read的代碼,返回一個數組,因為我們最終客戶端采用ArrayReader來解析數據。服務器端的代碼沒什么好解釋的,很簡單,再看客戶端的:
復制代碼 代碼如下:
<head>
<title>Data Proxy</title>
<link rel="Stylesheet" type="text/css" href="ext-3.1.0/resources/css/ext-all.css" />
<script type="text/Javascript" src="ext-3.1.0/adapter/ext/ext-base-debug.js"></script>
<script type="text/Javascript" src="ext-3.1.0/ext-all-debug.js"></script>
<script type="text/Javascript" src="ext-3.1.0/src/locale/ext-lang-zh_CN.js"></script>
<script type="text/Javascript">
var Student = Ext.data.Record.create(['id', 'Name', 'Telephone']);
var arrayReader = new Ext.data.ArrayReader({
root: 'r', idIndex: 0, fields: Student });
var httpProxy = new Ext.data.HttpProxy({
url: 'dataproxy.ashx',
api: {
read: 'dataproxy.ashx?action=read',
create: 'dataproxy.ashx?action=create',
update: 'dataproxy.ashx?action=update',
destroy: 'dataproxy.ashx?action=delete'
}
});
Ext.onReady(function() {
var form = new Ext.FormPanel({
renderTo: document.body,
height: 160,
width: 400,
frame: true,
labelSeparator: ':',
labelWidth: 60,
labelAlign: 'right',
defaultType: 'textfield',
items: [
{ fieldLabel: 'ID',
id: 'ID'
},
{ fieldLabel: 'Name',
id: 'Name'
},
{ fieldLabel: 'Telephone',
id: 'Telephone'
}
],
buttons: [{ text: 'Read', handler: function() {
httpProxy.doRequest('read', null, { id: form.getForm().findField('ID').getValue() }, arrayReader,
function(r, option, success) {
if (option.arrayData.success) {
var res = r.records[0];
Ext.Msg.alert('Result From Server', res.get('id') + ' ' + res.get('Name')
+' '+ res.get('Telephone'));
}
else {
Ext.Msg.alert('Result','Did not find.');
}

},this,arrayReader);
}
},
{ text: 'Delete' }, { text: 'Update' }, { text: 'Create'}]
})
});
</script>
</head>

這里有些東西要解釋下,首先是定義了一個Student的Record,這個和服務器端的代碼是一致的。然后定義了ArrayReader,ArrayReader是讀取數組內的數據,數據格式參考服務器端的代碼,它有一個root屬性非常重要,指定的是讀取json數據中哪個屬性的值(這個值是一個數組的字面量).idIndex也是必須指定的,它標志著哪個字段是主鍵。fields就好理解了,讀取的Record的字段。數組里邊的順序要和Record的字段順序對應,否則可以通過Record的mapping屬性來指定,例如: {name:'Telephone',mapping:4}就表示讀取數組中第4個數值放到Telephone字段中。 下面就是定義httpProxy,設置好api。然后我們創建一個表單:

image

添加4個按鈕。先為Read按鈕寫上處理函數:doRequest的一個參數是'read',第二個參數是null,因為我不懂它有什么用;第三個參數把要查詢的ID的值傳給服務器,第四個參數是一個reader,第五個參數callback很重要,我們在這里處理服務器的返回值。注意,我在最后一個參數設置為arrayReader,于是這個函數的option參數的值實際上就是arrayReader。我為什么要這樣做呢,一來是做個演示,最后一個參數有什么用,二來是因為ArrayReader比較古怪,注意它沒有公開的successProperty配置項,也就是說它無法判斷服務器返回的success屬性,也就是這個callback的success參數永遠是undefined!我一開始以為是我服務器端的代碼不對,后來debug進源代碼,發現它確實不處理這個success屬性。或許ArrayReader設計的本意就不是用在這個環境里的。不過作為演示,那就這樣用吧。其實它不處理success參數我們自己還是可以處理的。arrayReader內部有個arrayData屬性,它是一個解析好的json對象,如果返回的json字符串中有success屬性那么這個對象也有success屬性,這樣我們就可以獲得服務器的返回值,同理,也可以處理服務器返回的任何數據。當然,這種用法是文檔上沒有的,僅供演示。這個callback的第一個參數,要特別注意,文檔上說是Record[],不過實際上它是一個對象,它的record屬性才是Record[]。我只能說extjs這部分的文檔很糟糕。幸好這部分的代碼是很不錯的,有興趣的朋友可以調試進去看看,以便有更深刻的理解。好了,萬事俱備,點擊下Read按鈕,結果出來了:

image

此文暫告一段落,其他幾個操作原理上類似的,突然發現,如果單純的用這個例子來演示似乎不太合適。因為Delete和Update服務器端都不需要返回什么數據,而doRequest強制要求用一個DataReader來解析返回的數據,很不方便。或許在操作表格型的數據的時候doRequest的其他方法才有用武之地。針對單個對象的CRUD,可以直接采用更底層的Ext.ajax方法(另文介紹),或者利用表單的方法來處理。

本文只是對Extjs的數據模型的功能和原理做一簡單的介紹,在實際中如何高效的組織代碼和在服務器與客戶端間傳遞數據是一個另外的話題。Extjs還是很靈活的,客戶端和服務器端的通信契約還是可以讓程序員自己決定。

太長了…轉下篇…

JavaScript技術Extjs學習筆記之九 數據模型(上),轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 涩涩综合 | 91在线视频福利 | 四虎国产精品免费观看 | 色综合色狠狠天天久久婷婷基地 | 亚洲一区二区三区在线 | 1区2区3区4区 | 国产亚洲精品在天天在线麻豆 | 日韩欧美伊人久久大香线蕉 | 亚洲日本激情综合在线观看 | 国产91精品高清一区二区三区 | 国产精品亚洲一区二区三区正片 | 视色4se在线视频播放 | selaoban在线视频免费精品 | 国产亚洲精品网站 | 国产美女在线精品观看 | 国产精品福利在线观看 | 日本高清一区二区三区不卡免费 | 成人午夜性视频欧美成人 | 一日本道加勒比高清一二三 | 国产自精品在线 | 91三级在线观看 | 色香蕉影院| 加勒比日本在线 | 亚洲网站视频 | 91免费版视频 | 亚洲网色 | 久久综合色88 | 成人午夜大片免费7777 | 四虎永久在线精品国产免费 | 精品福利一区二区免费视频 | 成年人福利视频 | 久久久久青草大香线综合精品 | 91国语对白 | 欧美五月婷婷 | 国产成人精品免费2021 | 日韩一区国产二区欧美三区 | 亚洲网站一区 | 91妖精视频| 五月婷婷丁香 | 国产福利在线 | 夜色资源站www国产在线观看 |