javascript
Spring MVC,Ajax和JSON第3部分–客户端代码
如果您一直關(guān)注有關(guān)Spring,Ajax和JSON的簡短博客系列,那么您會回想起我到目前為止已經(jīng)創(chuàng)建了一個Spring MVC Web應(yīng)用程序,該應(yīng)用程序顯示一個表單,該表單允許用戶選擇一堆項目并向服務(wù)器提交購買請求。 然后,服務(wù)器用一些JSON進(jìn)行回復(fù),從而允許用戶確認(rèn)其購買。 如果您已經(jīng)知道所有這些,現(xiàn)在可以跳到此處 。 如果您想知道我在說什么,請閱讀本系列的前兩個博客:
- Spring MVC,Ajax和JSON第1部分–設(shè)置場景
- Spring MVC,Ajax和JSON第2部分–服務(wù)器端代碼
這里
完成服務(wù)器端代碼后,接下來要做的是繼續(xù)進(jìn)行客戶端代碼,其中涉及編寫一些JavaScript。 現(xiàn)在,在您我之間,我不是JavaScript專家,盡管我像大多數(shù)服務(wù)器端開發(fā)人員一樣,似乎一頭霧水。 對像我這樣的人來說,好消息是,在過去的幾年中,Javascript出現(xiàn)了突飛猛進(jìn)的發(fā)展,它提供了許多工具和庫來減輕開發(fā)的痛苦,而在所有這些之中,jQuery似乎已成為事實上的標(biāo)準(zhǔn)。依靠連鎖和“少寫多做”的哲學(xué)。
聲明了我正在使用jQuery的下一步是設(shè)置JSP,以便我可以開始編寫客戶端代碼。 如果查看shopping.jspHTML <head>元素,您將看到它包含以下鏈接:
<link rel="stylesheet" href="<c:url value='/resources/blueprint/screen.css'/>" type="text/css" media="screen, projection"/> <link rel="stylesheet" href="<c:url value='/resources/blueprint/print.css'/>" type="text/css" media="print" /> <!--[if lt IE 8]> <link rel="stylesheet" href="<c:url value='/resources/blueprint/ie.css' />" type="text/css" media="screen, projection" /> <![endif]-->??<link rel="stylesheet" href="<c:url value='/resources/style.css'/>" type="text/css" media="screen, projection"/>前三個鏈接是Blueprint的包含項,正如我在第一個博客中所說的那樣,它可以使我在屏幕格式設(shè)置方面的工作更加輕松。 指向style.css的最后一個鏈接很有趣。 它包含兩個我從Keith Donald的原始Spring MVC AJAX示例代碼中借用的css值。 這些css值是#mask和#popup ,它們應(yīng)用于我添加到我的JSP中的以下隱藏的div :
<div id="mask" style="display: none;"></div><div id="popup" style="display: none;"><div class="container" id="insertHere"><div class="span-1 append-23 last"><p><a href="#" onclick="closePopup();">Close</a></p></div></div></div>mask div用于使瀏覽器的內(nèi)容灰顯,而popup div用于顯示一個彈出框,我將在其中將AJAX調(diào)用的JSON結(jié)果寫入服務(wù)器。 請注意insertHere id,這在以后很重要……
JSPHTML head標(biāo)簽的最后兩行包括此頁面JavaScript文件:
<script type="text/javascript" src="<c:url value='/resources/jQuery-1.9.1.js' /> "></script><script type="text/javascript" src="<c:url value='/resources/shopping.js' /> "></script>這些導(dǎo)入的第一個是jQuery 1.9.1版。 版本在這里很重要。 如果您使用的是1.7.x或更低版本,則下面的javascript將無法正常工作,因為jQuery Guys更改了jQuery 1.8版本中AJAX調(diào)用的工作方式; 但是,如有必要,可以輕松修改JavaScript代碼。
第二個JavaScript導(dǎo)入是shopping.js ,其中包括此應(yīng)用程序所需的所有代碼,其關(guān)鍵是:
$(document).ready( function() { $('form').submit( function() { $('.tmp').remove();??? // Remove any divs added by the last request if (request) { request.abort();? // abort any pending request } var $form = $(this); // let's select and cache all the fields var $inputs = $form.find("input"); // serialize the data in the form var serializedData = $form.serialize(); // let's disable the inputs for the duration of the ajax request $inputs.prop("disabled", true); // fire off the request to OrderController var request = $.ajax({ url : "http://localhost:8080/store/confirm", type : "post", data : serializedData }); // This is jQuery 1.8+ // callback handler that will be called on success request.done(function(data) { console.log("Resulting UUID: " + data.uuid); $("<div class='span-16 append-8 tmp'><p>You have confirmed the following purchases:</p></div>") .appendTo('#insertHere'); var items = data.items; // Add the data from the request as <div>s to the pop up <div> for ( var i = 0; i < items.length; i++) { var item = items[i]; var newDiv = "<div class='span-4? tmp'><p>" + item.name + "</p></div>"; $(newDiv).appendTo('#insertHere'); newDiv = "<div class='span-6 tmp'><p>" + item.description + "</p></div>"; $(newDiv).appendTo('#insertHere'); newDiv = "<div class='span-4 append-10 last tmp'><p>£" + item.price + "</p></div>"; $(newDiv).appendTo('#insertHere'); console.log("Item: " + item.name + "? Description: " + item.description + " Price: " + item.price); } }); // callback handler that will be called on failure request.fail(function(jqXHR, textStatus, errorThrown) { // log the error to the console alert("The following error occured: " + textStatus, errorThrown); }); // callback handler that will be called regardless if the request failed or succeeded request.always(function() { $inputs.prop("disabled", false);? // re-enable the inputs }); event.preventDefault();?? // prevent default posting of form showPopup(); }); });所有操作都發(fā)生在已提交給jQuery的ready()函數(shù)的函數(shù)內(nèi)部,并且像JavaScript一樣,將函數(shù)傳遞給函數(shù)的函數(shù)也傳遞給函數(shù),即我之前所說的鏈接。 請記住,當(dāng)文檔“準(zhǔn)備就緒”可以進(jìn)行交互時,將調(diào)用ready()函數(shù)。
第一個內(nèi)部函數(shù)是$('form').submit(…) 。 如果您不了解jQuery,則$是jQuery庫的主要入口點,并且只是編寫jQuery簡寫形式。 在此調(diào)用中,我選擇了文檔中的所有表單(只有一個),并將一個函數(shù)參數(shù)傳遞給submit(…)方法。
關(guān)于jQuery的事情是,您可以使用它來選擇文檔模型中的對象,然后對它們執(zhí)行某些操作。 jQuery有自己的選擇技術(shù),該技術(shù)使用傳遞給jQuery(…)方法的字符串。 字符串具有以下基本格式:HTML元素(例如“ form”,“ a”,“ div”等)以純英語編寫,當(dāng)分別傳遞給jQuery時,將選擇
文檔中該HTML類型的所有實例。 帶有“。”的單詞 附加的是CSS值,而帶有'#'的單詞是html id屬性。 因此,例如,如果我寫了: $('form#bill').submit(...)那么我將選擇所有ID為bill表格,或者如果我寫了$('.fred').submit(…)然后選擇所有具有class屬性為fred文檔對象。 一旦掌握了這種查詢語言,其余的工作就一帆風(fēng)順。
當(dāng)涉及到j(luò)Query時,我發(fā)現(xiàn)O'Reilly jQuery Cookbook非常有用。
傳遞給$('form').submit(…)方法的函數(shù)是所有工作的發(fā)生地。 在發(fā)出Ajax請求之前,需要完成一些內(nèi)部整理任務(wù)。 其中包括刪除帶有tmp類的任何文檔對象(第一次調(diào)用它不會執(zhí)行任何操作,但此處不作介紹); 中止對服務(wù)器的任何未完成的請求(這在大多數(shù)情況下將不起作用); 禁用任何表單輸入并序列化Ajax請求將發(fā)布到服務(wù)器的數(shù)據(jù)。 JavaScript代碼的關(guān)鍵部分是
jQuery Ajax請求 :
該函數(shù)的格式通常為: ajax,url,settings 。 我使用的URL是http://localhost:8080/store/confirm ,它對應(yīng)于我上周描述的Spring RequestMapping 。 可以使用的設(shè)置是可選的鍵值對,并在jQuery Ajax文檔中進(jìn)行了詳細(xì)說明 。 在這種情況下,我將使用發(fā)布請求發(fā)送序列化的表單數(shù)據(jù)。
發(fā)出請求后,有幾個最終的家務(wù)任務(wù)要處理。 這些是為了防止HTML表單向服務(wù)器提交任何內(nèi)容,并“彈出”一個將Ajax請求的結(jié)果寫入其中的div。 這使用了前面提到的兩個ID為popup和mask div。
function showPopup() { $('body').css('overflow', 'hidden'); $('#popup').fadeIn('fast'); $('#mask').fadeIn('fast'); }回到Ajax請求… $.ajax(...)函數(shù)調(diào)用返回一個名為request的對象。 這是jqXHR類型,其中XHR的混淆縮寫代表XML HTTP Request 。 jqXHR對象是許多回調(diào)方法,旨在讓您的代碼處理某些事件。 在這種情況下,我實現(xiàn)了: fail(…) , always(…)和done(…) 。 在請求失敗的情況下,瀏覽器將調(diào)用fail(…)顯示一個簡單的alert(…) 。 always(…)是一種恰當(dāng)命名的方法,無論請求是成功還是失敗,該方法總是被調(diào)用。 在這種情況下,它將重新啟用所有表單的輸入類型。 最后,當(dāng)Ajax請求成功時,將調(diào)用done(…)方法。
request.done(function(data) { console.log("Resulting UUID: " + data.uuid); $("<div class='span-16 append-8 tmp'><p>You have confirmed the following purchases:</p></div>") .appendTo('#insertHere'); var items = data.items; // Add the data from the request as <div>s to the pop up <div> for ( var i = 0; i < items.length; i++) { var item = items[i]; var newDiv = "<div class='span-4? tmp'><p>" + item.name + "</p></div>"; $(newDiv).appendTo('#insertHere'); newDiv = "<div class='span-6 tmp'><p>" + item.description + "</p></div>"; $(newDiv).appendTo('#insertHere'); newDiv = "<div class='span-4 append-10 last tmp'><p>£" + item.price + "</p></div>"; $(newDiv).appendTo('#insertHere'); console.log("Item: " + item.name + "? Description: " + item.description + " Price: " + item.price); } });done(…)方法在這里最重要。 作為參數(shù),它傳遞了一個函數(shù),該函數(shù)的參數(shù)是我們感興趣的JSON數(shù)據(jù)。這不是任何舊的原始JSON字符串,jQuery將JSON轉(zhuǎn)換為具有uuid和items屬性的對象; 一個分身服務(wù)器端的OrderForm對象從我的最后的博客 。 使用此data對象,剩下要做的就是在屏幕上顯示結(jié)果。 這意味著遍歷數(shù)據(jù)并為每個OrderForm的屬性創(chuàng)建一個newDiv變量,并將其轉(zhuǎn)換為HTML。 這是簡單的字符串格式,例如:
"<div class='span-4 tmp'><p>" + item.name + "</p></div> "變成:
<div class='span-4 tmp'><p>Socks</p></div>該div包含一些有用的類屬性。 這些屬性是“ 藍(lán)圖”顯示屬性,稱為tmp 。 tmp class屬性與前面提到的$('.tmp').remove(); 呼叫。 當(dāng)用戶進(jìn)行多次提交時,此選項可用于從彈出div中刪除用戶先前的選擇。
創(chuàng)建了newDiv變量后,最后一步是使用帶有參數(shù)'#insertHere' jQuery的appendTo(…)函數(shù)將其附加到彈出div :
$(newDiv).appendTo('#insertHere');如果您運行該應(yīng)用程序,則現(xiàn)在將獲得以下購物表格,從中可以選擇要購買的商品:
現(xiàn)在,按確認(rèn)購買將從服務(wù)器請求JSON,對其進(jìn)行格式化并顯示以下彈出div:
除非我錯過任何事情,否則就是這樣。 這三個博客涵蓋了應(yīng)用程序的創(chuàng)建,添加服務(wù)器端代碼并??使用某些客戶端JavaScript對其進(jìn)行格式化。
最后有幾點。 首先,我不是Javascript或客戶端專家,因此,如果那里有發(fā)現(xiàn)錯誤的專家,那么我希望收到您的來信……其次,我忘了提及此項目的JSON部分是RESTFul ,因此要感謝Josh Long和他在Spring本周中的提及提醒我。 我想我并沒有提到這一點,因為作為一般規(guī)則,那么它應(yīng)該不用說每個應(yīng)用程序都應(yīng)盡可能使用RESTFul。
有關(guān)此博客的完整源代碼,請參見GitHub – https://github.com/roghughe/captaindebug/tree/master/ajax-json
參考: Spring MVC,Ajax和JSON第3部分– Captain Debug博客博客中來自JCG合作伙伴 Roger Hughes 的客戶端代碼 。翻譯自: https://www.javacodegeeks.com/2013/05/spring-mvc-ajax-and-json-part-3-the-client-side-code.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的Spring MVC,Ajax和JSON第3部分–客户端代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黄冰糖和白冰糖的区别(黄冰糖和白冰糖的区
- 下一篇: Spring JMS,消息自动转换,JM