久久精品水蜜桃av综合天堂,久久精品丝袜高跟鞋,精品国产肉丝袜久久,国产一区二区三区色噜噜,黑人video粗暴亚裔

Ajax- 動(dòng)態(tài)加載列表框

來自站長百科
跳轉(zhuǎn)至: 導(dǎo)航、? 搜索

導(dǎo)航: 上一頁 | ASP | PHP | JSP | HTML | CSS | XHTML | aJAX | Ruby | JAVA | XML | Python | ColdFusion

Web應(yīng)用通常使用“向?qū)Чぞ摺痹O(shè)計(jì)原則來構(gòu)建,即每個(gè)屏幕要求用戶輸入少量的信息,每個(gè)后續(xù)頁的數(shù)據(jù)都依據(jù)前一頁的輸入來創(chuàng)建。對(duì)于某些情況,這個(gè)設(shè)計(jì)模式非常有用,如用戶以一種逐步、有序的方式完成任務(wù)。遺憾的是,太多的Web應(yīng)用使用了這種方法,因?yàn)樗鼈儎e無選擇。在Ajax技術(shù)出現(xiàn)之前,當(dāng)基于用戶輸入修改頁面上的某些部分時(shí),動(dòng)態(tài)地更新頁面而不刷新整個(gè)頁面是很難辦到的,甚至根本不可能。

避免完全頁面刷新的一種技術(shù)是在頁面上隱藏?cái)?shù)據(jù),并在需要時(shí)再顯示它們。例如,假設(shè)選擇框B的值要根據(jù)選擇框A中所選值來填寫,此時(shí)選擇框B的所有可取值就可以放在隱藏的選擇框中。當(dāng)選擇框A中的所選值有變化時(shí),JavaScript可以確定要顯示哪一個(gè)隱藏的選擇框,然后將該選擇框置為可見,再把前一個(gè)選擇框置為隱藏。這種技術(shù)還可以變化一下,用隱藏列表框中的元素動(dòng)態(tài)填寫選擇框B中的option元素。這些技術(shù)都很有用,但是它們只在有限的情況下可用,即頁面中僅限于根據(jù)用戶輸入對(duì)有限的選擇進(jìn)行修改,而且這樣的選擇必須相對(duì)少。

假設(shè)你在構(gòu)建一個(gè)在線的汽車分類廣告服務(wù)。某人想購買汽車,指定了車型年份、品牌和車型,來搜索他想買的汽車。為了避免用戶的輸入錯(cuò)誤,并減少所需的動(dòng)態(tài)驗(yàn)證次數(shù),你決定車型年份、品牌和車型輸入字段都應(yīng)當(dāng)是選擇框,而且要考慮過去25年的車型廣告。如果車型年份選擇框或品牌選擇框中的選擇發(fā)生變化,就必須修改對(duì)應(yīng)該車型年份和品牌的可用車型列表。

要記住,對(duì)于每個(gè)車型年份,都會(huì)出現(xiàn)一些新的品牌,而一些老牌子可能會(huì)淡出人們的視線,所以其個(gè)數(shù)也會(huì)有變化。還要記住對(duì)于每種品牌來說,每年的車型都可能不同。如果有數(shù)十種品牌,每個(gè)車型年份每種品牌都有多種車型,那么車型年份、品牌和車型的組合數(shù)將是驚人的。由于有這么多的組合,只使用JavaScript來填寫選擇框是不可能的。

使用Ajax技術(shù)就能很輕松地解決這個(gè)問題。車型年份或品牌選擇框中的選擇每次有變化時(shí),會(huì)向服務(wù)器發(fā)出異步請(qǐng)求,要求得到該車型年份特定品牌的車型列表。服務(wù)器負(fù)責(zé)根據(jù)瀏覽器所請(qǐng)求的品牌和車型年份來確定車型列表。服務(wù)器很可能采用一種高速的數(shù)據(jù)查找組件(可能實(shí)現(xiàn)為一個(gè)關(guān)系數(shù)據(jù)庫),以完成查找可用車型的具體工作。一旦找到可用的車型,服務(wù)器把它們打包在一個(gè)XML文件中,并返回給瀏覽器。

瀏覽器負(fù)責(zé)解析服務(wù)器的XML響應(yīng),并用指定品牌和車型年份的可用車型來填寫車型選擇框。在這個(gè)例子中,要注意數(shù)據(jù)視圖與原始數(shù)據(jù)得到了很好的分離。瀏覽器只負(fù)責(zé)呈現(xiàn)數(shù)據(jù)視圖,服務(wù)器則負(fù)責(zé)挖掘必須呈現(xiàn)在瀏覽器視圖上的原始數(shù)據(jù)。

代碼清單4-5展示了如何使用Ajax技術(shù),從而根據(jù)另外兩個(gè)列表框的值動(dòng)態(tài)創(chuàng)建一個(gè)選擇框的內(nèi)容。這個(gè)例子的用例就是以上所述的分類廣告服務(wù),在此車型年份選擇框和品牌選擇框中的所選值決定了車型選擇框中的內(nèi)容。這個(gè)例子中只用了4個(gè)車型年份、3種品牌,以及對(duì)于某個(gè)車型年份、特定的品牌的4種可用車型。即便如此,車型年份、品牌和車型的組合數(shù)也達(dá)到了48。如果采用隱藏的辦法,即對(duì)應(yīng)每個(gè)車型年份和品牌組件,將相應(yīng)的車型列表隱藏起來,并根據(jù)所選的品牌和車型年份值來顯示適當(dāng)?shù)牧斜?,這是不可行的。

代碼清單4-5

dynamicLists.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns=" <head>
<title>Dynamically Filling Lists</title>
<script type="text/javascript">
var xmlHttp;
function createXMLHttpRequest() {
if (window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
}
function refreshModelList() {
var make = document.getElementById("make").value;
var modelYear = document.getElementById("modelYear").value;
if(make == "" || modelYear == "") {
clearModelsList();
return;
}
var url = "RefreshModelList?"
+ createQueryString(make, modelYear) + "&ts=" + new Date().getTime();
createXMLHttpRequest();
xmlHttp.onreadystatechange = handleStateChange;
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
function createQueryString(make, modelYear) {
var queryString = "make=" + make + "&modelYear=" + modelYear;
return queryString;
}
function handleStateChange() {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
updateModelsList();
}
}
}
function updateModelsList() {
clearModelsList();
var models = document.getElementById("models");
var results = xmlHttp.responseXML.getElementsByTagName("model");
var option = null;
for(var i = 0; i < results.length; i++) {
option = document.createElement("option");
option.appendChild
(document.createTextNode(results[i].firstChild.nodeValue));
models.appendChild(option);
}
}
function clearModelsList() {
var models = document.getElementById("models");
while(models.childNodes.length > 0) {
models.removeChild(models.childNodes[0]);
}
}
</script>
</head>
<body>
<h1>Select Model Year and Make</h1>
<form action="#">
<span style="font-weight:bold;">Model Year:</span>
<select id="modelYear" onchange="refreshModelList();">
<option value="">Select One</option>
<option value="2006">2006</option>
<option value="1995">1995</option>
<option value="1985">1985</option>
<option value="1970">1970</option>
</select>
<br/><br/>
<span style="font-weight:bold;">Make:</span>
<select id="make" onchange="refreshModelList();">
<option value="">Select One</option>
<option value="Chevrolet">Chevrolet</option>
<option value="Dodge">Dodge</option>
<option value="Pontiac">Pontiac</option>
</select>
<br/><br/>
<span style="font-weight:bold;">Models:</span>
<br/>
<select id="models" size="6" style="width:300px;">
</select>
</form>
</body>
</html>

頁面的更新由品牌和車型年份選擇框的onchange事件驅(qū)動(dòng)。只要這兩個(gè)選擇框中任何一個(gè)的所選值有變化,瀏覽器就會(huì)向服務(wù)器發(fā)出異步請(qǐng)求。發(fā)送請(qǐng)求時(shí)會(huì)攜帶一個(gè)查詢串,其中包含所選品牌和車型年份的值。

RefreshModelList servlet從瀏覽器接收到請(qǐng)求,并確定對(duì)應(yīng)指定品牌和車型年份的車型列表。這個(gè)servlet首先解析查詢串,確定所請(qǐng)求的品牌和車型年份。一旦確定了品牌和車型年份,servlet會(huì)迭代處理一個(gè)對(duì)象集合,其中每個(gè)對(duì)象分別表示一種車型年份、品牌和車型的組合。如果特定對(duì)象的車型年份和品牌屬性與所請(qǐng)求的車型年份和品牌匹配,則把這個(gè)對(duì)象的車型屬性增加到響應(yīng)XML串中。找到對(duì)應(yīng)指定品牌和車型年份的所有車型之后,將響應(yīng)XML寫回到瀏覽器。

請(qǐng)注意,在實(shí)際實(shí)現(xiàn)中,服務(wù)器端組件不太可能依賴硬編碼的值填寫選擇框,而是會(huì)搜索一個(gè)高速數(shù)據(jù)庫,查找所請(qǐng)求車型年份和品牌的相應(yīng)車型。

代碼清單4-6顯示了RefreshModelListServlet.java。

代碼清單4-6

RefreshModelListServlet.java
package ajaxbook.chap4;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.*;
import javax.servlet.http.*;
public class RefreshModelListServlet extends HttpServlet {
private static List availableModels = new ArrayList();
protected void processRequest(HttpServletRequest request
, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
int modelYear = Integer.parseInt(request.getParameter("modelYear"));
String make = request.getParameter("make");
StringBuffer results = new StringBuffer("<models>");
MakeModelYear availableModel = null;
for(Iterator it = availableModels.iterator(); it.hasNext();) {
availableModel = (MakeModelYear)it.next();
if(availableModel.modelYear == modelYear) {
if(availableModel.make.equals(make)) {
results.append("<model>");
results.append(availableModel.model);
results.append("</model>");
}
}
}
results.append("</models>");
response.setContentType("text/xml");
response.getWriter().write(results.toString());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
public void init() throws ServletException {
availableModels.add(new MakeModelYear(2006, "Dodge", "Charger"));
availableModels.add(new MakeModelYear(2006, "Dodge", "Magnum"));
availableModels.add(new MakeModelYear(2006, "Dodge", "Ram"));
availableModels.add(new MakeModelYear(2006, "Dodge", "Viper"));
availableModels.add(new MakeModelYear(1995, "Dodge", "Avenger"));
availableModels.add(new MakeModelYear(1995, "Dodge", "Intrepid"));
availableModels.add(new MakeModelYear(1995, "Dodge", "Neon"));
availableModels.add(new MakeModelYear(1995, "Dodge", "Spirit"));
availableModels.add(new MakeModelYear(1985, "Dodge", "Aries"));
availableModels.add(new MakeModelYear(1985, "Dodge", "Daytona"));
availableModels.add(new MakeModelYear(1985, "Dodge", "Diplomat"));
availableModels.add(new MakeModelYear(1985, "Dodge", "Omni"));
availableModels.add(new MakeModelYear(1970, "Dodge", "Challenger"));
availableModels.add(new MakeModelYear(1970, "Dodge", "Charger"));
availableModels.add(new MakeModelYear(1970, "Dodge", "Coronet"));
availableModels.add(new MakeModelYear(1970, "Dodge", "Dart"));
availableModels.add(new MakeModelYear(2006, "Chevrolet", "Colorado"));
availableModels.add(new MakeModelYear(2006, "Chevrolet", "Corvette"));
availableModels.add(new MakeModelYear(2006, "Chevrolet", "Equinox"));
availableModels.add(new MakeModelYear(2006, "Chevrolet", "Monte Carlo"));
availableModels.add(new MakeModelYear(1995, "Chevrolet", "Beretta"));
availableModels.add(new MakeModelYear(1995, "Chevrolet", "Camaro"));
availableModels.add(new MakeModelYear(1995, "Chevrolet", "Cavalier"));
availableModels.add(new MakeModelYear(1995, "Chevrolet", "Lumina"));
availableModels.add(new MakeModelYear(1985, "Chevrolet", "Cavalier"));
availableModels.add(new MakeModelYear(1985, "Chevrolet", "Chevette"));
availableModels.add(new MakeModelYear(1985, "Chevrolet", "Celebrity"));
availableModels.add(new MakeModelYear(1985, "Chevrolet", "Citation II"));
availableModels.add(new MakeModelYear(1970, "Chevrolet", "Bel Air"));
availableModels.add(new MakeModelYear(1970, "Chevrolet", "Caprice"));
availableModels.add(new MakeModelYear(1970, "Chevrolet", "Chevelle"));
availableModels.add(new MakeModelYear(1970, "Chevrolet", "Monte Carlo"));
availableModels.add(new MakeModelYear(2006, "Pontiac", "G6"));
availableModels.add(new MakeModelYear(2006, "Pontiac", "Grand Prix"));
availableModels.add(new MakeModelYear(2006, "Pontiac", "Solstice"));
availableModels.add(new MakeModelYear(2006, "Pontiac", "Vibe"));
availableModels.add(new MakeModelYear(1995, "Pontiac", "Bonneville"));
availableModels.add(new MakeModelYear(1995, "Pontiac", "Grand Am"));
availableModels.add(new MakeModelYear(1995, "Pontiac", "Grand Prix"));
availableModels.add(new MakeModelYear(1995, "Pontiac", "Firebird"));
availableModels.add(new MakeModelYear(1985, "Pontiac", "6000"));
availableModels.add(new MakeModelYear(1985, "Pontiac", "Fiero"));
availableModels.add(new MakeModelYear(1985, "Pontiac", "Grand Prix"));
availableModels.add(new MakeModelYear(1985, "Pontiac", "Parisienne"));
availableModels.add(new MakeModelYear(1970, "Pontiac", "Catalina"));
availableModels.add(new MakeModelYear(1970, "Pontiac", "GTO"));
availableModels.add(new MakeModelYear(1970, "Pontiac", "LeMans"));
availableModels.add(new MakeModelYear(1970, "Pontiac", "Tempest"));
}
private static class MakeModelYear {
private int modelYear;
private String make;
private String model;
public MakeModelYear(int modelYear, String make, String model) {
this.modelYear = modelYear;
this.make = make;
this.model = model;
}
}
}

如圖4-6所示,在任何一個(gè)選擇框中選擇不同的值,就會(huì)更新車型列表。
Image006.jpg