分享
 
 
 

Web Application 開 發 利 器 - WebSnap(十三)

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Web Application 開 發 利 器 - WebSnap!

第 十 三 章 、 Adapter 與 Wrapper

我 們 在 前 面 幾 節 都 稍 稍 的 提 到 Adapter 及 Wrapper 之 間 的 關 係 , 我 們 都 知 道 , WebSnap 利 用 Adapters 加 上 Wrapper 來 串 接 Code 與 Script , 但 是 我 們 一 直 沒 有 真 正 詳 細 的 檢 視 她 們 是 如 何 合 作 , 特 定 的 Adapter 又 提 供 了 那 一 個 Wrapper , 這 裡 我 們 就 詳 細 的 討 論 她 們 吧 !

13-1 Wrapper Object 與 Adapter Component

( 圖 :9)

上 圖 中 我 們 可 以 了 解 , 當 我 們 在 Script 中 下 達 Application.Today.Value 這 個 Script 命 令 時 , 其 實 我 們 正 在 操 作 一 個 Adapter Wrapper Object , 藉 由 這 個 Adapter Wrapper Object , 我 們 可 以 操 作 到 位 於 DELPHI 程 式 中 的 Adapter Component , 當 Application 這 個 Adapter Wrapper Object 接 到 .Today 這 個 屬 性 要 求 時 , 她 會 將 動 作 轉 向 至 位 於 DELPHI 程 式 中 的 Adapter Component , 找 到 Today 這 個 Adapter Field Component , 然 後 建 立 一 個 Adapter Field Wrapper Object 傳 回 給 Active Script , 我 們 也 就 可 以 在 Active Script 使 用 這 個 Adapter Field Wrapper Object 來 操 作 位 於 DELPHI 程 式 中 的 Adapter Field Component 取 得 Value 值 了 , 其 實 所 謂 的 Wrapper Object 就 是 我 們 熟 悉 的 COM 物 件 , 所 以 我 們 才 能 在 Active Script 中 操 作 她 們 , 因 此 當 你 完 成 了 一 個 WebSnap 程 式 後 , 你 要 將 這 些 COM 物 件 安 裝 在 Web-Server 的 電 腦 上 , 這 樣 才 能 正 常 執 行 WebSnap 程 式 , DELPHI 6 附 了 一 個 簡 易 的 Windows Installer: InstallShield Express 3.5 , 你 可 以 在 Delphi6\MergeModules 中 找 到 相 關 的 安 裝 檔 案 。

13-2 Modules(Global)

這 是 全 域 型 的 Wrapper , 基 本 上 她 是 橋 接 WebContext 中 的 WebModules , 讓 我 們 可 以 列 出 目 前 程 式 所 有 已 建 立 的 Module , 或 是 利 用 她 來 取 得 特 定 的 Module , 當 然 ! 這 個 Module 必 需 是 已 建 立 的 , 以 下 是 列 出 所 有 已 建 立 的 Modules Script 程 式 :

<%

mdlist=new Enumerator(Modules)

s = ''

for (; !mdlist.atEnd(); mdlist.moveNext())

{

s+='<h3>'+mdlist.item().Name_+'</h3>'

}

Response.Write(s)

%>

Response 是 另 一 個 全 域 型 Wrapper , 我 們 會 在 下 面 談 到 , 她 的 功 能 就 與 ASP 內 的 Response 一 樣 , 輸 出 字 串 到 目 的 HTML 文 件 中 。 我 們 也 可 以 利 用 Modules 來 取 得 特 定 的 Module:

<% var M = Modules.Home %>

並 經 由 這 個 Module Wrapper 取 得 她 裡 面 所 包 含 的 Wrapper 物 件 :

<%= M.Adapter1.TestField.Value%>

13-3 Application(Global)

她 是 ApplicationAdapter 的 Wrapper 物 件 , 你 可 以 經 由 她 取 得 Application.Title 這 個 值 :

<%= Application.Title %>

或 是 你 在 on-line help 中 所 看 到 的 完 整 路 徑 範 例 :

<%

function PathInfoToRelativePath(S)

{

var R = '';

var L = S.length

I = 0

while (I < L)

{

if (S.charAt(I) == '/')

R = R + '../'

I++

}

return R

}

function QualifyImage(S)

{

if (Application.Designing)

return Application.QualifyFileName("..\\images\\" + S); // relative directory

else

return PathInfoToRelativePath(Request.PathInfo) + '../images/' + S; // virtual directory

}

%>

這 個 程 式 是 用 來 取 得 程 式 的 絕 對 路 徑 或 是 虛 擬 站 台 的 URL , 由 於 我 們 在 Visual Page Designer 的 Preview 功 能 中 需 要 的 是 絕 對 路 徑 , 但 在 實 際 網 站 中 需 要 的 是 URL , 因 此 她 提 供 了 Designing 特 性 值 讓 我 們 判 別 目 前 是 處 於 Visual Page Designer 還 是 實 際 站 台 中 , 在 這 個 程 式 中 QualifyFileName 就 是 取 得 絕 對 路 徑 的 函 式 , 其 中 的 ..\\ 會 往 上 移 一 層 , 假 設 絕 對 路 徑 是 c:\temp\examples1\ , 那 結 果 就 是 c:\temp\images\ + S 。

由 於 ApplicationAdapter 也 是 Adapter 其 中 的 一 員 , 因 此 我 們 也 可 以 像 操 作 Adapter 一 樣 操 作 她 :

<%=Application.Today.Value%>

也 可 以 利 用 Adapter 的 Fields 來 取 出 所 有 的 AdapterField

<%

adlist=new Enumerator(Application.Fields)

s = ''

for (; !adlist.atEnd(); adlist.moveNext())

{

s+='<h3>'+adlist.item().Name+'</h3>'

}

Response.Write(s)

%>

或 是 Actions 物 件

<%

adlist=new Enumerator(Application.Actions)

s = ''

for (; !adlist.atEnd(); adlist.moveNext())

{

s+='<h3>'+adlist.item().Name+'</h3>'

}

Response.Write(s)

%>

其 它 的 部 份 你 可 以 參 考 下 面 的 Adapter Wrapper 。

13-4 Request(Global)

與 ASP 中 的 Request 物 件 意 義 一 樣 , 用 來 取 得 HTTP Request 的 一 些 資 訊 , 你 可 以 在 Script 中 加 入 以 下 的 Script 碼 就 明 白 了 :

<h3><%=Request.PathInfo%></h3>

<h3><%=Request.ScriptName%></h3>

<h3><%=Request.Host%></h3>

13-5 Response(Global)

等 同 ASP 中 的 Response 物 件 , 我 想 你 應 該 很 清 楚 用 途 才 是 !

13-6 EndUser(Global)

她 是 EndUserAdapter 的 Wrapper , 技 術 上 來 說 , 不 管 你 有 沒 有 放 至 EndUserAdapter 到 AppModule 上 , 她 都 會 被 建 立 出 來 , 只 是 實 體 物 件 有 沒 有 被 建 立 而 已 , 因 此 你 可 以 安 全 的 在 Script 使 用 她 , 而 不 在 意 EndUserAdapter 存 不 存 在 :

<% if (EndUser.Logout != null) { %>

<% if (EndUser.DisplayName != '') { %>

<h1> 歡 迎 <%=EndUser.DisplayName %> 你 今 年 是 <%=EndUser.AdaptAge.Value%> 歲 </h1><% } %>

<% if (EndUser.Logout.Enabled) { %>

<a href="<%=EndUser.Logout.AsHREF%>">Logout</a>

<% } %>

<% if (EndUser.LoginForm.Enabled) { %>

<a href=<%=EndUser.LoginForm.AsHREF%>>Login</a>

<% } %>

<% } %>

她 與 ApplicationAdapter 一 樣 , 都 屬 於 Adapter 類 , 因 此 你 也 可 以 像 使 用 一 般 的 Adapter 一 樣 使 用 她 , 上 面 的 程 式 有 展 示 這 一 點 , Logout 及 LoginForm 都 是 AdapterAction , 下 面 會 談 到 這 個 Wrapper 。

13-7 Session(Global)

她 與 ASP 中 的 Session 物 件 大 致 相 同 , 她 Wrapper 了 TWebSession 物 件 , 與 EndUser 相 同 , 不 管 你 有 沒 有 放 至 SessionsService 她 都 會 被 建 立 出 來 , 只 是 有 沒 有 實 體 物 件 而 已 , 你 可 以 利 用 Session.SessionID.Value 來 取 得 SessionID 的 值 , 也 可 以 利 用 Session.Value (名 稱) 來 取 得 Session 中 的 值 。

<%=Session.SessionID.Value%>

<%=Session.Values('Age')%>

13-8 Page

她 Wrapper 了 WebPageInfo , 也 就 是 你 在 Page Module 最 後 一 行 中 的 設 定 值 :

<h3><%=Page.Title%></h3>

<h3><%=Page.Name%></h3>

<h3><%=Page.HREF%></h3>

<h3><%=Page.Description%></h3>

<h3><%=Page.LoginRequired%></h3>

<h3><%=Page.CanView%></h3>

<h3><%=Page.DefaultAction.Name%></h3>

紅 色 的 部 份 在 使 用 時 要 特 別 小 心 , 因 為 Page 中 不 一 定 要 有 DefautlAction , 因 此 她 有 可 能 是 空 值 , 而 且 取 得 DefaultAction 會 引 發 Page Module 的 自 動 建 立 動 作 , CanView 及 LoginRequired 是 用 來 管 理 使 用 者 及 權 限 控 制 用 。

13-9 Producer

技 術 上 她 與 Response 大 致 相 同 , 只 是 它 可 以 寫 入 HTML Tag:

<h3><%Producer.Write('我是 <#NameTag>')%></h3>

接 著 你 就 可 以 在 Producer 的 OnHTMLTag 事 件 中 取 代 這 個 Tag , 如 果 寫 入 的 資 料 不 是 HTML Tag 的 話 , 使 用 Response 會 較 有 效 率 。

13-10 Adapter

標 準 的 AdapterWrapper , 指 的 是 TAdapter 或 是 TDataSetAdapter 等 , 她 提 供 了 Fields,Actions 兩 個 列 舉 器 , 我 們 可 以 經 由 她 們 列 出 AdapterFields 及 AdapterActions:

<%

adlist=new Enumerator(Application.Fields)

s = ''

for (; !adlist.atEnd(); adlist.moveNext())

{

s+='<h3>'+adlist.item().Name+'</h3>'

}

Response.Write(s)

%>

<%

adlist=new Enumerator(Application.Actions)

s = ''

for (; !adlist.atEnd(); adlist.moveNext())

{

s+='<h3>'+adlist.item().Name+'</h3>'

}

Response.Write(s)

%>

當 一 個 網 頁 執 行 了 Action 後 發 生 錯 誤 導 向 錯 誤 網 頁 時 , 我 們 可 以 利 用 她 的 Errors 來 取 出 錯 誤 訊 息 :

<%

var e = new Enumerator(Modules.CountryTable.Adapter.Errors)

for (; !e.atEnd(); e.moveNext())

{

Response.Write("<li>" + e.item().Message)

}

e.moveFirst()

%>

當 使 用 的 Adapter 有 多 筆 資 料 時 , 例 如 TDataSetAdapter 跟 之 前 我 們 所 撰 寫 的 MyAdapter , 我 們 可 以 利 用 Records 列 舉 器 來 移 動 記 錄 位 置 :

<%var e = new Enumerator(vdsAdaptCust.Records)

for (; !e.atEnd(); e.moveNext())

{ %>

<tr>

<% if (vdsAdaptCust_Filter.Visible)

{ %>

<td><div><% obj=CheckBoxGroup(vdsAdaptCust_Filter, vdsAdaptCust_Filter.InputName,

1, '')%><%=obj.text%></div></td><% } %>

你 可 以 在 AdapterGrid 中 所 產 生 的 Script 看 到 一 樣 的 運 用 方 式 , 當 你 把 AdapterGrid 的 AdapterMode 設 為 Edit 時 , 你 還 可 以 看 到 HiddenFields 及 HiddenRecordFields , 這 兩 個 Wrapper 可 以 將 Adapter 中 的 隱 藏 欄 位 用 WriteFields 寫 到 HTML 中 , 這 用 在 DataSetAdapter 上 , 你 可 以 在 AdaterAction 一 節 中 找 到 相 關 的 資 訊 , HiddenFields 及 HiddenRecordFields 中 的 資 訊 會 受 到 DataSetAdapterField 中 的 FieldFlags 特 性 值 的 影 響 , 就 像 是 以 往 我 們 熟 悉 的 UpdateFlag 一 樣 。 CanModify 及 CanView 則 是 權 限 控 制 的 部 份 , Mode 這 個 特 性 值 是 用 來 判 別 目 前 的 網 頁 所 處 的 狀 態 , 例 如 Edit,Insert,Query 等 DataSetAdapter 所 提 供 的 狀 態 , 技 術 上 你 可 以 用 撰 寫 元 件 的 方 式 定 義 自 己 的 AdapterMode 及 Adapter, 在 Inside WebSnap 中 有 一 個 這 樣 的 範 例 。

13-11 AdapterAction

AdapterAction 的 Wrapper Object , 我 們 可 以 在 Grid Page 中 的 Script 看 到 以 下 的 Script:

onclick="AdapterForm2.__act.value='<%=vAdapter1_Query.LinkToPage("Edit", "Error").AsFieldValue%>

這 會 編 出 以 下 的 HTML

__sp.4.Edit__fp.5.Error__id.19.Grid.Adapter1.Query

各 參 數 的 詳 細 用 途 請 參 考 AdapterAction 一 節 。 Style 特 性 值 與 AdapterAction 中 IGetHTMLStyle.GetDisplayType 相 呼 應 , 可 以 用 來 取 得 Action 的 顯 示 方 式 , 如 button,image,link 等 等 , Array 可 以 讓 我 們 列 出 該 Action 所 支 援 的 命 令 , 較 明 顯 的 範 例 是 PagedAdapter 的 GotoPage Script:

<%

// GotoPage has a list of commands. Loop through the list. Only use an anchor tag if the command

// is enabled

if (vGotoPage.Array != null)

{

var e = new Enumerator(vGotoPage.Array)

for (; !e.atEnd(); e.moveNext())

{

%>

<td>

<% if (vGotoPage.Enabled)

{ %>

<a href="<%=vGotoPage.LinkToPage(Page.Name).AsHREF%>">

<%=vGotoPage.DisplayLabel%></a>

<% }

else

{ %>

<a><%=vGotoPage.DisplayLabel%></a>

<% }

%>

</td>

<%

}

}

%>

13-12 AdapterField

我 想 你 對 她 應 該 相 當 熟 悉 了 , InputName 這 個 特 性 值 有 個 技 術 是 很 重 要 的 , 你 只 要 比 對 TDataSetAdapter 與 TAdapter 所 產 生 出 來 的 HTML 就 可 以 了 解 到 她 跟 Records 有 很 大 的 牽 連 , 在 AdapterGrid 情 況 下 InputName 後 面 的 數 字 代 表 著 資 料 記 錄 位 置 , 當 AdapterGrid Post 之 後 , 這 些 值 就 會 被 送 往 Action , 接 著 我 們 就 可 以 利 用 ActionRequest 與 ActionFieldValues 來 取 出 這 些 值 , InputStyle 則 是 HTML Control 類 型 , DisplayType 與 AdapterAction.Style 作 用 相 同 , 只 是 對 象 是 Text,Image,List , ViewMode 是 顯 示 模 式 : Input 與 Display , DisplayText 與 EditText 則 是 AdapterField 的 值 , 通 常 在 顯 示 text 時 我 們 使 用 DisplayText , input 時 使 用 EditText , ValuesList 則 是 傳 回 AdapterField 中 ValueList 的 Wrapper Object 。

13-13 AdapterErrors

就 是 Adapter 的 錯 誤 資 訊 , 也 就 是 我 們 在 Adapter Wrapper Object 所 展 示 的 列 舉 錯 誤 真 正 的 物 件 。

<%

var e = new Enumerator(Modules.CountryTable.Adapter.Errors)

for (; !e.atEnd(); e.moveNext())

{

Response.Write("<li>" + e.item().Message)

}

e.moveFirst()

%>

13-14 AdapterFieldValues

這 用 在 AdapterField 支 援 Multi-Value 時 , 如 HTML List Control 等 多 選 值 情 況 下 , 目 前 是 TAdapterMultiValueField 。 你 可 以 用 以 下 的 程 式 碼 來 取 出 這 些 值

var e = new Enumerator(f.Values.Records)

for (; !e.atEnd(); e.moveNext())

{

s+= '<li>'

s += f.Values.ValueField.DisplayText;

s += '</li>'

c++

}

e.moveFirst()

13-15 AdapterFieldValuesList

這 是 我 們 由 AdapterField.ValueList 所 傳 回 來 的 Wrapper Object , 使 用 方 式 大 略 與 上 面 那 一 個 相 同 , 不 過 多 加 了 可 傳 回 AdapterImage 的 能 力 與 直 接 用 Name 來 取 值 的 函 式 。

13-16 AdapterHiddenFields

就 是 我 們 使 用 Adapter.HiddenFields 所 傳 回 來 的 Wrapper 物 件 。

13-17 AdapterImage

使 用 AdapterField.Image 所 傳 回 來 的 Wrapper Object , 提 供 了 圖 形 的 URL 。

本章後記

WebSnap 中 的 Wrapper Object 大 概 就 是 這 些 , 我 本 來 不 想 將 這 些 列 出 來 的 , 因 為 這 些 東 西 在 更 新 的 Help 檔 中 有 詳 細 的 說 明 及 範 例 檔 , 只 是 有 部 份 蠻 模 糊 的 , 因 此 我 決 定 就 一 些 會 造 成 疑 問 的 部 份 說 明 , 請 你 參 照 著 On-Line Help 看 , 會 有 較 完 整 的 認 識 。

<附錄A、 一些小技巧>

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有