




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、Tapestry4開發(fā)指南 一, 簡介使用“開發(fā)指南”這個(gè)名詞,實(shí)在是慚愧。隨著接觸面的增廣,隨著各種技術(shù)的不斷了解,才逐漸發(fā)現(xiàn)自己欠缺得更多。書讀得越多,才發(fā)覺自己的知識越匱乏。半年前,非常自不量力地將自己對Tapestry3.0.x的實(shí)踐總結(jié)出來,寫了一個(gè)所謂的Tapestry開發(fā)指南,而現(xiàn)在Tapestry4發(fā)布,我覺得將這個(gè)所謂的“開發(fā)指南”更新到Tapestry4,對自己來說,更像是一種交代。有很多不足之處,希望朋友們能夠不遺余力地指出,就是對我最大的支持。Tapestry4的雛形是Tapestry3.1,Tapestry的作者Howard,不光開發(fā)了Tapestry,還同時(shí)開發(fā)了一
2、個(gè)輕量級框架Hivemind。所以Tapestry3.1的開發(fā)一開始就處于Hivemind框架之下。后來由于種種原因,Howard沒有將Tapestry3.1從Hivemind中剝離出來,于是就成為了今天的Tapestry4.0。很多朋友都不是很認(rèn)同Hivemind,認(rèn)為Hivemind是與Spring類似的IoC框架。剛開始的時(shí)候,我也同樣很不認(rèn)同Hivemind,畢竟使用Spring很熟悉了。而且我們團(tuán)隊(duì)的整個(gè)技術(shù)架構(gòu)已經(jīng)日趨成熟。就如同我當(dāng)初評價(jià)Tapestry4與Hivemind之間的融合:“除非有足夠且必要的理由,不然別說讓我去說服團(tuán)隊(duì)將Spring轉(zhuǎn)型為Hivemind,就連我自己
3、都說服不了自己?!彪S著對Tapestry4的深入,我開始理解為什么Howard沒有將Tapestry從Hivemind中剝離。就團(tuán)隊(duì)而言,我依然不認(rèn)為有必要說服團(tuán)隊(duì)轉(zhuǎn)型。但是就我個(gè)人而言,僅僅在IoC和DI的使用上,我卻覺得使用Hivemind比Spring簡單。當(dāng)然,簡單并非最重要的理由,但是當(dāng)我們處于某一個(gè)特殊條件下,或許使用Hivemind也不失一個(gè)值得參考的選擇。另外,最重要的是,如果著眼于Tapestry本身,Hivemind就好比是一個(gè)良好的地基,Tapestry作為上層建筑,任何我們認(rèn)為不合理,不適合自己特殊需要的Tapestry官方實(shí)現(xiàn),都可以通過Hivemind的IoC及DI
4、進(jìn)行重構(gòu)。于是,現(xiàn)在的Tapestry4變得非常有趣,首先,它本身是一個(gè)框架,可以使用Tapestry4來創(chuàng)建動(dòng)態(tài),靈活的web應(yīng)用程序,另外,可以通過Hivemind對Tapestry4自身功能進(jìn)行重構(gòu),以便實(shí)現(xiàn)任何我們希望達(dá)到的特殊功能。打個(gè)比方說:Tapestry4就好比一把起子,我們可以通過Hivemind對這把起子的起子頭進(jìn)行任意更換,這樣我們就可以適應(yīng)任何形狀或者接口的螺絲。在后面,我們會看到令人興奮的示例來介紹這種“換起子頭”的思想。關(guān)于Tapestry4.0的理論知識,如果有興趣,可以參看我以前寫的,關(guān)于Tapestry3.0的開發(fā)指南。實(shí)際上,雖然版本升級了,使用方式也有了很
5、大變化,但是Tapestry本質(zhì)的思想和理論并沒有變化。這就是為什么雖然Tapestry4.0才剛剛發(fā)布,我卻可以比別人更快地熟悉Tapestry4.0的使用。對于理論的介紹,這里就不在累述了。記得我以前學(xué)習(xí)Tapestry3.0的時(shí)候,還是通過查詢Tapestry2.4的理論資料來學(xué)習(xí)的。對于本文檔,我希望定位在快速熟悉Tapestry4.0。凡是我在本文檔中提到的組件,如果沒有做特別解釋,那么就表示其用法與T3中基本相同,而對于T3的組件,我在以前些的文檔中已經(jīng)介紹了絕大部分。所以如果你是新手,建議你先參看我以前寫的文檔(二, Quick Start現(xiàn)在Tapestry4已經(jīng)發(fā)布beta-
6、9版本,從其change log上,我們可以看到,Tapestry4的開發(fā)已經(jīng)日趨成熟,基本上官方現(xiàn)在修改最多的都已經(jīng)僅僅是文檔。所以,我現(xiàn)在已經(jīng)在使用Tapestry4來開發(fā)項(xiàng)目。為了配合這篇user guide,我寫了一個(gè)quick start示例。我們可以一步一步從項(xiàng)目配置開始,逐步了解Tapestry4。1) 搭建環(huán)境我們需要如下東東:Eclipse3.1及其以上版本:/downloads/index.phpMyEclipse4.0及其以上版本:Java SE 5.0及其以上版本:Resin3.0.x:Tapestry4.0包:http:/ja
7、/site/downloads/downloads_tapestry.cgiTapestry4.0支持包:/tapestry/dependencies.htmlOK,現(xiàn)在我們開始搭建Tapestry項(xiàng)目。對于Eclipse的配置,我們就略過了。使用MyEclipse新建一個(gè)Web Project:我們將項(xiàng)目名稱命名為MyTapestry4:點(diǎn)擊Finish,我們新建了一個(gè)Web Project:然后我們將下載好的Tapestry4及其支持包拷貝到WEB-INF/lib/目錄中:然后將包文件載入項(xiàng)目:OK,基本的項(xiàng)目
8、配置完成,現(xiàn)在我們在src下新建包:com.tapestry4: 然后在WEB-INF目錄下新建一個(gè)XML文件,命名為hivemind.xml,內(nèi)容如下:在這里,hivemind.xml中module的id是與java包名com.tapestry4對應(yīng)的,這個(gè)id只是起標(biāo)識的作用,因?yàn)镠ivemind可以擁有很多的配置文件,所以一般都使用包名作為id以保證唯一性。接著,我們在WEB-INF/目錄下再新建一個(gè)application文件MyTapestry4.application,其內(nèi)容如下:在application文件中,我們做了兩件事:第一:聲明了項(xiàng)目名稱:name=”MyTapestry4
9、”;第二:我們定義了page文件與java文件相互對應(yīng)的默認(rèn)包路徑,Tapestry4根據(jù)這個(gè)路徑自動(dòng)去尋找與Home.page同名的Home.java文件,如果找不到,那么就會默認(rèn)使用BasePage類。然后我們進(jìn)行web.xml配置:為了測試項(xiàng)目是否已經(jīng)正常配置,我們可以做點(diǎn)小測試:首先在com.tapestry4下新建一個(gè)Home.java文件:在Tapestry4中,java文件可以不再是abstract的,這個(gè)差別相比于Tapestry3還是很突出的。因?yàn)橐粋€(gè)很簡單的理由,一旦Tapestry4的java文件不再是抽象類,那么就可以進(jìn)行單元測試了。在后面,我們會看到如何進(jìn)行單元測試。
10、接著在WEB-INF/下建一個(gè)Home.page文件:最后,我們在web/目錄下新建一個(gè)Home.html文件:2) 讓我們的項(xiàng)目跑起來將resin解壓到硬盤,當(dāng)然,使用tomcat,jetty等,都可以用下面的方式來啟動(dòng)項(xiàng)目。首先,打開Eclipse的Window -> Preference :在MyEclipse的Application Server選項(xiàng)下,我們找到Resin3,然后在右邊進(jìn)行Resin配置。首先指定Resin Server為Enable,然后指定Resin Home Directory地址。然后我們要確保JDK的版本是否正確,并且加載兩條JVM參數(shù):-Dorg.ap
11、ache.tapestry.disable-caching=true-Dorg.apache.tapestry.enable-reset-service=true使用過Tapestry3的朋友對這兩條參數(shù)都非常熟悉了,它們的作用是關(guān)閉Tapestry的頁面緩存,這樣就能夠讓我們在開發(fā)項(xiàng)目的時(shí)候,修改html和page之后,不需要頻繁地重新啟動(dòng)項(xiàng)目。但是在加載這兩條參數(shù)之后,內(nèi)存消耗比較大,所以在項(xiàng)目發(fā)布的時(shí)候,我們就不再使用這兩條參數(shù)了。一旦你正確地配置了Resin,我們就可以在MyEclipse中啟動(dòng)Resin了。首先點(diǎn)擊MyEclipse的J2EE項(xiàng)目配置管理:然后在下拉菜單中選擇我們的M
12、yTapestry4項(xiàng)目,點(diǎn)擊右邊的Add按鈕:選擇我們已經(jīng)配置好的Resin Server,最后點(diǎn)擊Finish。OK,現(xiàn)在我們可以清楚地看到,我們的項(xiàng)目已經(jīng)被部署到Resin的deploy目錄下了。接著,我們啟動(dòng)Resin,就可以啟動(dòng)我們的項(xiàng)目了:在Eclipse的控制臺,我們可以清楚地看到項(xiàng)目啟動(dòng)的整個(gè)過程:嘿嘿,OK了。我們的項(xiàng)目已經(jīng)搭建成功,打開一個(gè)瀏覽器,在地址欄中輸入::8080/MyTapestry4/app其實(shí)搭建Tapestry4項(xiàng)目,很簡單吧?0J三, 更深入使用Tapestry4.0現(xiàn)在,我們還是和以前一樣,做一個(gè)最熟悉的示例:購物車。只是
13、這次我們手把手一步一步地完成這個(gè)示例。1)登陸OK,現(xiàn)在項(xiàng)目已經(jīng)搭建完成了,對于購物車示例,第一個(gè)頁面應(yīng)該是一個(gè)登陸頁面。登陸頁面應(yīng)該有一個(gè)表單,有一個(gè)用戶名輸入,一個(gè)密碼輸入,同時(shí)還需要對用戶名和密碼進(jìn)行效驗(yàn)。修改Home.java文件如下:package com.tapestry4;import org.apache.tapestry.IRequestCycle;import org.apache.tapestry.html.BasePage;public abstract class Home extends BasePage /用戶名public abstract String get
14、Username();/密碼public abstract String getPassword();/登陸表單的監(jiān)聽方法public void loginSubmit(IRequestCycle cycle) System.out.println(this.getUsername();System.out.println(this.getPassword();在Home.page文件中,我們修改如下:<?xml version="1.0" encoding="GBK"?><!DOCTYPE page-specification PUB
15、LIC "-/Apache Software Foundation/Tapestry Specification 4.0/EN" "/tapestry/dtd/Tapestry_4_0.dtd"><page-specification> <property name="username"/> <property name="password"/> <component id="loginForm" t
16、ype="Form"> <binding name="listener" value="listener:loginSubmit"/> </component> <component id="username" type="TextField"> <binding name="value" value="username"/> </component> <component id=&q
17、uot;password" type="TextField"> <binding name="value" value="password"/> <binding name="hidden" value="true"/> </component></page-specification>首先我們看到的是對username和password兩個(gè)property的定義,與Tapestry3不同的是,現(xiàn)在Tapestry4.0不需要為pr
18、operty指定類型,也就是說,Tapestry4.0會根據(jù)程序?qū)嶋H運(yùn)行時(shí)裝載到property的數(shù)據(jù)來自動(dòng)轉(zhuǎn)換對應(yīng)的類型。在java中,我們聲明了兩個(gè)property調(diào)用的抽象方法:/用戶名public abstract String getUsername();/密碼public abstract String getPassword();因此,即便不用在page中聲明這兩個(gè)property的類型,Tapestry4.0也知道它們是String。接著我們聲明了三個(gè)組件:<component id="loginForm" type="Form"&
19、gt; <binding name="listener" value="listener:loginSubmit"/> </component><component id="username" type="TextField"> <binding name="value" value="username"/> </component> <component id="password" typ
20、e="TextField"> <binding name="value" value="password"/> <binding name="hidden" value="true"/> </component>Form組件和TextField組件的基本定義和用法與Tapestry3.0差不多,所以對其原理這里就不再累述。對于Home.html我們修改如下:<html><body><table width="33%
21、" border="1"> <form jwcid="loginForm"> <tr> <td width="32%" align="center">登陸</td> <td width="68%" align="center" valign="middle"> </td> </tr> <tr> <td width=&quo
22、t;32%" align="left">用戶名:</td> <td width="68%" align="left"><input type="text" jwcid="username"/></td> </tr> <tr> <td align="left">密碼:</td> <td align="left"><input ty
23、pe="password" jwcid="password"/></td> </tr> <tr> <td align="left"> </td> <td align="center"><input type="submit" value="登陸"/></td> </tr> </form></table></body&
24、gt;</html>在Html中嵌入jwcid與Tapestry3.0一樣,只是唯一不同的是,在Tapestry4.0中,“jwcid”這個(gè)名詞可以修改為你任意指定的單詞。現(xiàn)在,開啟服務(wù)器,啟動(dòng)項(xiàng)目,我們會看見一個(gè)表單頁面:然后我們輸入用戶名和密碼,就可以看見eclipse的控制臺打印出對應(yīng)的值:其實(shí)仔細(xì)看看Home.java中的loginSubmit監(jiān)聽方法,其IRequestCycle參數(shù)我們并沒有使用,所以,該監(jiān)聽方法可以簡便為:/登陸表單的監(jiān)聽方法public void loginSubmit() System.out.println(this.getUsername();
25、System.out.println(this.getPassword();現(xiàn)在,我們再增加一些表單效驗(yàn),比如,我們要求進(jìn)行客戶端用戶名和密碼效驗(yàn),它們都必須輸入,而且密碼必須大于6位字符,于是修改Home.page中的Form組件和TextField組件聲明為:<component id="loginForm" type="Form"> <binding name="listener" value="listener:loginSubmit"/> <binding name=&quo
26、t;clientValidationEnabled" value="true"/> </component> <component id="username" type="TextField"> <binding name="value" value="username"/> <binding name="validators" value="validators:required"/> &l
27、t;binding name="displayName" value="literal:【用戶名】"/> </component> <component id="password" type="TextField"> <binding name="value" value="password"/> <binding name="hidden" value="true"/> <b
28、inding name="validators" value="validators:required,minLength=6"/> <binding name="displayName" value="literal:【密碼】"/> </component>運(yùn)行項(xiàng)目之后,我們忽然發(fā)現(xiàn)如下頁面:從Tapestry4的報(bào)錯(cuò)頁面中,我們發(fā)現(xiàn),原來一旦對TextField添加客戶端效驗(yàn),就必須讓其運(yùn)行在Body組件之中,那么我們在Home.html的<body>標(biāo)簽中添加Body
29、組件:<body jwcid=”Body”>再次訪問Home頁面,OK,一切正常:也許你覺得非常奇怪,我們并沒有寫任何JavaScript代碼,那么又如何完成客戶端的JavaScript效驗(yàn)?zāi)兀窟@就是Tapestry組件動(dòng)態(tài)script的魅力了。在這里我們使用的Form組件,在Tapestry4.0中,F(xiàn)orm組件自帶了一些動(dòng)態(tài)script代碼,不論Form組件使用在任何情況下的任何項(xiàng)目中,只要開啟<binding name="clientValidationEnabled" value="true"/>就可以實(shí)現(xiàn)JavaScri
30、pt效驗(yàn)。Tapestry的組件就好比一個(gè)黑盒子,動(dòng)態(tài)script就好比這個(gè)盒子中一塊我們不需要了解的JavaScript代碼,只要我們按動(dòng)這個(gè)“盒子”上的一個(gè)“開關(guān)”,動(dòng)態(tài)Script就會通過Tapestry框架自動(dòng)生成適應(yīng)當(dāng)前表單的JavaScript代碼。因此,即便這段動(dòng)態(tài)Script不是我自己寫的,我同樣可以毫無顧忌地使用。2)水果商店OK,現(xiàn)在登陸已經(jīng)實(shí)現(xiàn)了,現(xiàn)在我們來為“購物車”添加一些商品,假設(shè)我們都是賣水果的:我們定義一個(gè)普通的水果VO:package com.tapestry4;public class Fruit private Integer id; private St
31、ring name; / 名稱private float price; / 單價(jià)private int mount; / 數(shù)量public int getMount() return mount;public void setMount(int mount) this.mount = mount;public String getName() return name;public void setName(String name) = name;public float getPrice() return price;public void setPrice(float p
32、rice) this.price = price;public Integer getId() return id;public void setId(Integer id) this.id = id;然后定義一個(gè)商品業(yè)務(wù)邏輯類:package com.tapestry4;import java.util.ArrayList;import java.util.List;public class Products private static List<Fruit> productList;public static List<Fruit> getProductList(
33、) if(productList=null) productList = new ArrayList<Fruit>();productList.add(createFruit(1, "蘋果", 1.00f, 20);productList.add(createFruit(2, "西瓜", 0.80f, 10);productList.add(createFruit(3, "桔子", 1.50f, 25);productList.add(createFruit(4, "梨子", 2.00f, 30);re
34、turn productList;public static Fruit createFruit(Integer ig, String name, float price, int mount) Fruit fruit = new Fruit();fruit.setId(ig);fruit.setName(name);fruit.setPrice(price);fruit.setMount(mount);return fruit;public static Fruit findFruitById(Integer ig) if(productList = null) productList =
35、getProductList();Fruit fruit = null;for(Fruit f : productList) if(f.getId().intValue() = Value() fruit = f;return fruit;現(xiàn)在,我們需要一個(gè)展示商品的頁面,命名為FirstPage:Shop.javapackage com.tapestry4;import java.util.List;import org.apache.tapestry.html.BasePage;public class Shop extends BasePage public List get
36、FruitList() return Products.getProductList();Shop.page<page-specification><property name="fruit"/> <component id="fruitListLoop" type="Foreach"> <binding name="source" value="fruitList"/> <binding name="value" val
37、ue="fruit"/> <binding name="element" value="literal:tr"/> </component> <component id="fruitName" type="Insert"> <binding name="value" value=""/> </component> <component id="fruitP
38、rice" type="Insert"> <binding name="value" value="fruit.price"/> </component> </page-specification>Shop.html<html><body><table width="419" border="1"> <tr align="center"> <td width="
39、240">水果名稱</td> <td width="139">單價(jià)</td> </tr> <tr jwcid="fruitListLoop" align="center"> <td><span jwcid="fruitName">名稱</span></td> <td><span jwcid="fruitPrice">單價(jià)</span>元&
40、lt;/td> </tr></table></body></html>為了能夠在登陸之后,跳轉(zhuǎn)到商品目錄頁面FirstPage,我們需要對Home.java進(jìn)行修改:public abstract class Home extends BasePage /用戶名public abstract String getUsername();/密碼public abstract String getPassword();InjectPage("Shop")public abstract FirstPage getShopPage
41、();/登陸表單的監(jiān)聽方法public IPage loginSubmit(IRequestCycle cycle) System.out.println(this.getUsername();System.out.println(this.getPassword();return this. getShopPage ();注意監(jiān)聽方法loginSubmit的返回參數(shù),在這里,直接返回FirstPage頁面的實(shí)例即可跳轉(zhuǎn)到FirstPage頁面。InjectPage("Shop")是Tapestry4.0新提供的annotation包中的一個(gè)annotation。凡是該an
42、notation所聲明的抽象getter方法,均會獲取到指定頁面的實(shí)例。在這里就獲取到FirstPage頁面的實(shí)例。在輸入用戶名和密碼之后,我們就可以跳轉(zhuǎn)到新頁面了:3) 購買水果為了購買水果,我們需要為Shop頁面的每個(gè)水果名稱添加一個(gè)鏈接,一旦用戶點(diǎn)擊該種水果,我們就跳轉(zhuǎn)到一個(gè)水果購買頁面,該頁面顯示了水果的詳細(xì)信息并且可以讓用戶輸入購買的數(shù)量。為Shop頁面的每個(gè)水果名稱添加鏈接:修改Shop.html:package com.tapestry4;import java.util.List;import org.apache.tapestry.IPage;import org.apach
43、e.tapestry.annotations.InjectPage;import org.apache.tapestry.html.BasePage;public abstract class Shop extends BasePage InjectPage("BuyFruit")public abstract BuyFruit getBuyFruitPage();public List getFruitList() return Products.getProductList();public IPage buyFruit(Integer ig) BuyFruit pag
44、e = this.getBuyFruitPage();page.setFruitId(ig);return page;修改Shop.page:<page-specification><property name="fruit"/> <component id="fruitListLoop" type="Foreach"> <binding name="source" value="fruitList"/> <binding name=&quo
45、t;value" value="fruit"/> <binding name="element" value="literal:tr"/> </component> <component id="fruitName" type="Insert"> <binding name="value" value=""/> </component> <componen
46、t id="fruitPrice" type="Insert"> <binding name="value" value="fruit.price"/> </component> <component id="buyFruitLink" type="DirectLink"> <binding name="listener" value="listener:buyFruit"/> &l
47、t;binding name="parameters" value="fruit.id"/> </component> </page-specification>修改Shop.html:<html><body><table width="419" border="1"> <tr align="center"> <td width="240">水果名稱</td> <td
48、width="139">單價(jià)</td> </tr> <tr jwcid="fruitListLoop" align="center"> <td><a href="#" jwcid="buyFruitLink"><span jwcid="fruitName">名稱</span></a></td> <td><span jwcid="frui
49、tPrice">單價(jià)</span>元</td> </tr></table></body></html>從上面的修改可以看出,我們添加了一個(gè)DirectLink組件,該組件的監(jiān)聽方法是public IPage buyFruit(Integer ig),并傳遞參數(shù)<binding name="parameters" value="fruit.id"/>。熟悉T3的朋友會發(fā)現(xiàn),T4中監(jiān)聽方法的用法有很大區(qū)別,現(xiàn)在我們看到的是監(jiān)聽方法的另外一種用法。直接將Dire
50、ctLink傳遞的輸入?yún)?shù)作為其監(jiān)聽方法的參數(shù)。一旦DirectLink觸發(fā)監(jiān)聽方法,我們直接就可以從監(jiān)聽方法的輸入?yún)?shù)中獲取到被傳遞過來的fruit.id。當(dāng)然,監(jiān)聽方法的輸入?yún)?shù)是與fruit.id類型相對應(yīng)的。public IPage buyFruit(Integer ig) BuyFruit page = this.getBuyFruitPage();page.setFruitId(ig);return page;在這個(gè)監(jiān)聽方法中,我們獲取到了DirectLink傳遞的參數(shù),并且我們向下一個(gè)頁面?zhèn)鬟f水果的ID值,在下一個(gè)頁面,我們就可以根據(jù)這個(gè)ID值,查找到對應(yīng)的水果詳細(xì)信息。水果詳細(xì)
51、信息頁面:BuyFruitPage.javapackage com.tapestry4;import java.util.ArrayList;import java.util.List;import org.apache.tapestry.html.BasePage;public class BuyFruit extends BasePage private Integer fruitId;private int buyMount;Overrideprotected void initialize() fruitId = null;buyMount = 0;/ 獲取水果詳細(xì)信息public F
52、ruit getFruitDetail() return Products.findFruitById(this.getFruitId();/ 購買水果SuppressWarnings("deprecation")public String buyFruitSubmit() FruitCart fc = new FruitCart();Fruit f = Products.findFruitById(this.getFruitId();fc.setBuyFruit(f);fc.setBuyMount(this.getBuyMount();fc.setPayMoney(f.g
53、etPrice() * this.getBuyMount();MyVisit visit = (MyVisit)this.getVisit();List<FruitCart> list = visit.getFruitCartList();if(list = null) list = new ArrayList<FruitCart>();list.add(fc);visit.setFruitCartList(list);return "Cart"/ 重新選擇水果public String backShopSubmit() return "S
54、hop"public Integer getFruitId() return fruitId;public void setFruitId(Integer fruitId) this.fruitId = fruitId;public int getBuyMount() return buyMount;public void setBuyMount(int buyMount) this.buyMount = buyMount;BuyFruitPage.page<page-specification> <component id="fruitName"
55、; type="Insert"> <binding name="value" value="fruitD"/> </component> <component id="fruitPrice" type="Insert"> <binding name="value" value="fruitDetail.price"/> </component> <component
56、 id="fruitMount" type="Insert"> <binding name="value" value="fruitDetail.mount"/> </component> <component id="buyFruitForm" type="Form"> <binding name="clientValidationEnabled" value="true"/>&l
57、t;/component><component id="fruitIdHidden" type="Hidden"> <binding name="value" value="fruitId"/></component> <component id="fruitBuyMount" type="TextField"> <binding name="value" value="buyMount
58、"/> <binding name="translator" value="translator:number"/> <binding name="displayName" value="literal:購買數(shù)量"/> </component> <component id="buyFruitSubmit" type="Submit"> <binding name="listener" v
59、alue="listener:buyFruitSubmit"/> </component> <component id="backShopSubmit" type="Submit"> <binding name="listener" value="listener:backShopSubmit"/> </component></page-specification>BuyFruitPage.html<html><
60、body jwcid="Body"><form jwcid="buyFruitForm"><span jwcid="fruitIdHidden"/><table width="242" border="1"> <tr align="center"> <td width="121">水果名稱</td> <td width="105"><span
61、 jwcid="fruitName">名稱</span></td> </tr> <tr align="center"> <td>單價(jià)</td> <td><span jwcid="fruitPrice">1.00</span>元</td> </tr> <tr align="center"> <td>存貨</td> <td><sp
62、an jwcid="fruitMount">20</span>斤</td> </tr> <tr align="center"> <td>購買數(shù)量</td> <td><input type="text" jwcid="fruitBuyMount" size="3" length="3"/>斤</td> </tr> <tr align="c
63、enter"> <td><input type="submit" jwcid="backShopSubmit" value="重新選擇"/></td> <td><input type="submit" jwcid="buyFruitSubmit" value="購買"/></td> </tr></table></form></body><
64、;/html>當(dāng)在Shop頁面選擇水果之后,我們通過DirectLink向這個(gè)頁面?zhèn)鬟f了一個(gè)水果ID。然后,在下面的方法中,我們獲得了詳細(xì)的水果信息:/獲取水果詳細(xì)信息public Fruit getFruitDetail() return Products.findFruitById(this.getFruitId();這個(gè)方法返回的是一個(gè)Fruit對象,因此我們直接通過Insert組件,將水果信息輸出到頁面上。<component id="fruitName" type="Insert"> <binding name="value" value="fruitD"/> </component> <component id="fruitPrice" type="Insert"> <binding name="value" value="fruitDetail.pr
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 養(yǎng)老護(hù)理員試題及答案
- 海淀高考試題及答案
- 團(tuán)委活動(dòng)電信活動(dòng)方案
- 國慶貓咪活動(dòng)策劃方案
- 圓明園活動(dòng)策劃方案
- 團(tuán)委活動(dòng)迎元旦活動(dòng)方案
- 品味民俗活動(dòng)方案
- 周末活動(dòng)策劃方案
- 團(tuán)課熱身活動(dòng)方案
- 售樓處射擊活動(dòng)方案
- 中國紅色文化精神學(xué)習(xí)通超星課后章節(jié)答案期末考試題庫2023年
- 平方差公式公開課一等獎(jiǎng)?wù)n件市公開課一等獎(jiǎng)?wù)n件省賽課獲獎(jiǎng)?wù)n件
- 2023年公司商業(yè)機(jī)密保密管理
- 《古生物學(xué)》講義
- 山東農(nóng)業(yè)大學(xué)工程造價(jià)與招投標(biāo)(專升本)期末考試復(fù)習(xí)題
- 2023山西焦煤集團(tuán)有限責(zé)任公司井下操作工招聘2000人筆試模擬試題及答案解析
- 中國西部國際汽車城可行性研究報(bào)告(上)
- 通信工程施工組織方案
- 火災(zāi)報(bào)警系統(tǒng)操作及維護(hù)保養(yǎng)規(guī)程(保得威爾)
- 靜脈輸液工具合理選擇
- GB/T 9634.2-2002鐵氧體磁心表面缺陷極限導(dǎo)則第2部分:RM磁心
評論
0/150
提交評論