ajax - 介面、表單、模板引擎
1.
今天繼續ajax的一個學習,首先明確一個觀念,介面,什麼是介面,當使用ajax請求資料時,被請求的url就叫做資料介面也就是介面,注意每個介面必須有請求方式,這裡有一個介面的測試工具,postman自稱是全球最快的,反正使用起來沒多大毛病,使用這個軟體的時候有一個注意點就是在post請求的時候,在body裡面輸入引數要選擇x-www-form-這個選項才行,然後是介面文件,我們如果要呼叫介面,那肯定是要參照介面文件的,裡面的包含這個介面的所有資訊,一般一個介面文件大致分為以下五個內容:
①介面名稱:能夠一眼看出這個介面是個什麼型別的介面
②url:這個不用多說,介面的呼叫地址
③呼叫方式:會給你說明這個介面要用get還是post
④引數格式:介面需傳遞的引數,每個引數必須包含引數名稱、引數型別以及引數說明
⑤響應格式:介面返回值的描述,一般包含資料名稱型別說明
2.
然後繼續看到一個普遍應用,表單,我們說的form表單一般是拿來收集資料的,然後再form裡面有一些屬性比如
action表示向何處傳送表單資料,如果未指定就是當前頁面
target是在何處開啟這個action,就跟a標籤的一樣
method是傳送action的方式可以為get或者post預設是get,get適合用來提交一些簡單資料的,post適合提交複雜資料,我們在專案中用到post居多
enctype是規定傳送表單資料前如何對資料進行編碼,一般預設是前面提到的x-www-form-urlencoded,但是這裡要注意下如果說是包含檔案上傳的表單的話,這裡的值要改為multipart/form-data
繼續看到表單的同步提交,就是當你一點選提交,頁面就會發生跳轉到action的地址上去,這樣的使用者體驗極差,而且頁面之前的資料和狀態都會丟失,怎麼來解決這一現象,我們只需要讓表單控制元件負責採集資料,ajax來負責提交即可。
如果要用到ajax跟表單的一個配合,首先要知道一個事件也就是submit提交事件,然後在這裡面組織表單預設行為,因為每次一點提交就會重新整理頁面,然後通過一個函式可快速獲取到表單的資料,。serialize()使用這個有個前提就是必須為表單裡面每個元素新增name屬性就像面這樣
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form action="/login"> <input type="text" name="uname"> <input type="password" name="password"> <input type="submit" value="提交"> </form> <script src="../day01/lib/jquery.js"></script> <script> $('form').on('submit', e => { console.log(11); e.preventDefault() // 這裡鬧了個大烏龍,剛開始我是用的$(this)我就說為什麼一直獲取不到資料思來想去也就是這裡的問題應該,後來才知道我這裡明明用的是 // 箭頭函式啊,箭頭函式的this是誰啊能亂用嗎? var str = $('form').serialize() console.log(str); }) </script> </body> </html>
案例:評論列表,頁面還是才去bootstrap,vscode可安裝bs3實現快速bootstrap程式設計,這個案例就是通過介面先獲取評論列表的資料,渲染到html上,然後通過介面發表評論
.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="../day01/lib/bootstrap.css"> <script src="../day01/lib/jquery.js"></script> </head> <body style="padding: 15px;"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">發表評論</h3> </div> <div class="panel-body"> <form> <div>評論人</div> <input type="text" class="form-control" name="username"> <div>內容</div> <textarea class="form-control" name="content"></textarea> <button type="submit" class="btn btn-primary">發表評論</button> </form> </div> </div> <ul class="list-group"> </ul> <script> // 1.獲取評論列表資料 function getComment() { $.ajax({ type : 'get', url : 'http://www.liulongbin.top:3006/api/cmtlist', success : res => { console.log(res); if (res.status !== 200) { return alert('獲取評論列表失敗') } else { $('.list-group').empty() $.each(res.data, (i, item) => { $('.list-group').append(`<li class="list-group-item"> <span class="badge" style="background-color: #f0ad4e;">評論時間:${item.time}</span> <span class="badge" style="background-color: #5bc0de;">評論人:${item.username}</span> ${item.content} </li>`) }) } } }) } getComment() // 2.發表評論 $('form').on('submit', function(e) { e.preventDefault() var str = $('form').serialize() // console.log(str); $.post('http://www.liulongbin.top:3006/api/addcmt', str,res => { if (res.status !== 201) { return alert('發表評論失敗') } else { getComment() // 2.1 提交成功後應該將表單的內容清空,這裡有個快捷方法,直接將form用她的reset方法,但是要先將jq轉為原生物件 $('form')[0].reset() } }) }) </script> </body> </html>
3.
繼續看到一個概念叫做模板引擎,看過我之前的案例都知道,我們之前渲染ul的時候都是採取的字串拼接的方式,對res裡面的資料進行遍歷,進行字串拼接,而反覆的進行字串拼接產生的影響就不多多說了吧,大量耗費記憶體資源,所以這個時候就產生了一種模板引擎就是程式設計師根據指定模板結構和資料,自動生成一個完整的html介面。
那麼當下比較優秀的模板引擎之一 art-template使用它有幾個步驟分為安裝、匯入、定義資料、定義模板、呼叫template、渲染html,這裡面還有一些注意事項
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div></div> <script src="../day01/lib/jquery.js"></script> <!-- 1.首先第一步肯定是要匯入下載的template模板版引擎js --> <script src="./template-web.js"></script> <script type="text/html" id="model"> <!-- // 3.然後第三步定義模板注意也是script來書寫,然後還有一個注意點因為平時寫的script基本上是text/JavaScript意思就是script裡面解析的 // 的是js程式碼,但是這裡我們既然是html模板所以就不能憶原來那種方式來預設 --> <!-- 這樣一新增,連註釋都變了 --> <!-- 3.1這裡還有一個注意點,在template模板裡面變數的佔位符是兩個花括號 --> <!-- 3.2這裡裡面的變數寫什麼就寫資料裡面的屬性名即可 --> <span>{{name}}</span> </script> <script> // 2.匯入後其實在js當中就存在了一個template的函式,你一輸的話它是有關鍵字出來的 // 第二步需要定義資料 var data = {name : '張三'} // 4.定義完後繼續在這裡呼叫template函式 // 4.1這個函式有兩個引數,也是為什麼前面要定義兩個東西的原因,第一個引數是模板的id(這個id新增在剛在定義模板的script中,而且並不用寫#),第二個引數是需要渲染的物件 // 4.2呼叫完後會有一個返回值注意用一個變數去儲存 var strHtml = template('model', data) // 5.都結束後就是最後的渲染到HTML中 console.log(strHtml); $('div').html(strHtml) </script> </body> </html>
關於模板引擎的使用記住上面我說的步驟就行了,在這個定義模板裡面我們用到了一個佔位符{{}}這個裡面的寫法是有講究的,我們叫做標準語法
①正常輸出 可以在裡面寫{{value/obj.key/arr[0]/a ? a : b}} 這些簡單複雜資料都是可以寫在裡面的
②原義輸出 就是如果value是一個html結構那麼你要讓他在渲染的時候顯示出來就需要在前面新增一個@ {{@value}}
③條件輸出 {{if 條件}} 執行語句 {{/if}} 當然你可以在中間穿插{{else if 條件}}
④迴圈輸出 {{each 迴圈的變數}} 在這裡面有兩個值可以使用 {{$value}}當前鄉的值 {{$當前項的索引}} {{/each}}
⑤過濾器 就是當你對{{value}}的值不滿意的時候你可以{{value | filterName}} 然後再js程式碼裡面template.defaults.imports.filterName = function(value) {}對這個值進行修改,注意return出這個處理結果,這個filtername是可以自定義的
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div></div> <script src="../day01/lib/jquery.js"></script> <!-- 1.首先第一步肯定是要匯入下載的template模板版引擎js --> <script src="./template-web.js"></script> <script type="text/html" id="model"> <!-- // 3.然後第三步定義模板注意也是script來書寫,然後還有一個注意點因為平時寫的script基本上是text/JavaScript意思就是script裡面解析的 // 的是js程式碼,但是這裡我們既然是html模板所以就不能憶原來那種方式來預設 --> <!-- 這樣一新增,連註釋都變了 --> <!-- 3.1這裡還有一個注意點,在template模板裡面變數的佔位符是兩個花括號 --> <!-- 3.2這裡裡面的變數寫什麼就寫資料裡面的屬性名即可 --> <span>{{name}}</span> <div>{{regTime | dateFormat}}</div> </script> <script> template.defaults.imports.dateFormat = function(date) { var y = date.getFullYear() var m = date.getMonth() + 1 var d = date.getDate() return y + '-' + m + '-' + d } // 2.匯入後其實在js當中就存在了一個template的函式,你一輸的話它是有關鍵字出來的 // 第二步需要定義資料 var data = {name : '張三',regTime : new Date()} // 4.定義完後繼續在這裡呼叫template函式 // 4.1這個函式有兩個引數,也是為什麼前面要定義兩個東西的原因,第一個引數是模板的id(這個id新增在剛在定義模板的script中,而且並不用寫#),第二個引數是需要渲染的物件 // 4.2呼叫完後會有一個返回值注意用一個變數去儲存 var strHtml = template('model', data) // 5.都結束後就是最後的渲染到HTML中 console.log(strHtml); $('div').html(strHtml) </script> </body> </html>
4.
我們繼續看到正則與字串的操作,其實解釋來看一下模板引擎的一個原理,首先明確一個正則的函式。exec()可以檢索字串中滿足正則表示式的,有就返回,沒有就返回null。
然後是分組我們將正則裡面用括號包起來的內容叫做一個分組,可以通過分組來提取想要的內容。
然後看到replace,其實這些包括正則前面都說過的也可以看前面的一個博文,replace就是字串的替換方法,可以將引數裡面前面一個替換為後面一個。先說到這裡看一個程式碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let str = '我是{{name}}' let reg = /{{([a-zA-Z]+)}}/ let regResult = reg.exec(str) console.log(regResult); </script> </body> </html>
多次replace
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let str = '我叫{{name}}今年{{age}}歲了' let reg = /{{\s*([a-zA-Z]+)\s*}}/ str1 = reg.exec(str) str = str.replace(str1[0],str1[1]) console.log(str); str1 = reg.exec(str) str = str.replace(str1[0],str1[1]) console.log(str); str1 = reg.exec(str) console.log(str1); </script> </body> </html>
有沒有感覺上面的程式碼有點冗餘,沒錯這裡是可以通過迴圈來實現的
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> var str = '我叫{{name}}今年{{age}}歲了' var reg = /{{\s*([a-zA-Z]+)\s*}}/ var result = reg.exec(str) while (result) { str = str.replace(result[0], result[1]) result = reg.exec(str) } console.log(str); </script> </body> </html>
然後replace替換為真值,很簡單很小的一個改動
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> var data = {name : '張三', age : 19} var str = '我叫{{name}}今年{{age}}歲了' var reg = /{{\s*([a-zA-Z]+)\s*}}/ var result = reg.exec(str) while (result) { str = str.replace(result[0], data[result[1]]) result = reg.exec(str) } console.log(str); </script> </body> </html>
ok這一系列結束過後我們自己就可以來定義一個簡易版的模板引擎,把剛才說的正則字串與模板引擎的規則結合起來
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="./template.js"></script> </head> <body> <div class="box"></div> <!-- 1.定義模板結構 --> <script type="text/html" id="model"> <div>姓名:{{name}}</div> <div>年齡:{{ age }}</div> <div>性別:{{ gender}}</div> <div>住址:{{address }}</div> </script> <!-- 2.預呼叫模板引擎 --> <script> // 3.模板引擎函式 // 2.1定義資料 var data = { name : '張三', age : 14, gender : '男', address : '重慶市江北區' } // 2.2呼叫 var strModel = template('model', data) console.log(strModel); // 2.3渲染 document.querySelector('.box').innerHTML = strModel </script> </body> </html>