jQuery Ajax API 實作以及 Template 介紹

前陣子在上前端基礎課,有教大家怎麼利用 jQuery AJAX 實現簡單的 CRUD 效果,後來覺得這對初學者來說,應該是個需要反覆思考才能融會貫通的小門檻,剛好最近也有學生對此表示不懂😱,所以就借這篇文章簡單跟大家介紹囉!

我會用在課堂上的教材跟大家拆解語法,但為了避免大家練習時灌爆我的 API,所以我不會透露 API 網址,一律用變數ajax_url代替。


什麼是 API

用程式介面(英語:Application Programming Interface,簡稱:API),又稱為應用編程介面,就是軟體系統不同組成部分銜接的約定。
維基百科

對網站開發人員而言,API 就是前後端溝通的一個接口。後端可以透過各種方法操作資料庫裡的資料;但對前端來說,我們該怎麼操作資料呢?我們可以利用後端人員提供的 API(通常是一串網址)去操作資料,只要有了 API,我們就可以用 JavaScript 搭配 AJAX 實現 CRUD 。

如果還是霧煞煞也沒關係,接下來會用程式碼讓大家加深印象,原理神馬的,可以透過實作去了解 😊。

什麼是 CRUD

CRUD 是四個單字的簡稱,就像我們在學 CSS 時一定要會使用選擇器(selector),而後端在學操作資料庫時,一定要先會 CRUD。
這四個單字分別意思為:

  • C:Create (新建資料)
  • R:Read (讀取資料)
  • U:Update (更新資料)
  • D:Delete (刪除資料)

實作留言板的 CRUD

接下來要跟大家分享的是,如何透過前端實作一個留言板,這個留言板要有 CRUD 的功能,就是我們常說的:新增、刪除、修改 留言。

那因為新增留言是我這期學生的期末考題,所以等他們考完試,我會再把新增留言的程式碼放上來,現在我們先來學習刪除、修改,以及顯示留言吧😋

在此先用 Bootstrap 做了一個非常簡單的留言版,你可以在 HTML 裡面看到要放留言的區塊,只有一行 <div class="result"></div>,其他什麼都沒有。

<div class="container">
	<div class="row">
		<div class="col-xs-8 col-xs-offset-2">
			<form class="form">
				<input type="text" id="inputName" class="form-control" placeholder="姓名" required autofocus>
				<input type="email" id="inputEmail" class="form-control" placeholder="電子郵件" required autofocus>
				<input type="text" id="inputUrl" class="form-control" placeholder="http://" autofocus>
				<input type="text" id="inputTitle" class="form-control" placeholder="文章標題" required autofocus>
				<textarea id="Message" style="width: 100%;" rows="10"></textarea>
				<button class="btn btn-lg btn-primary btn-block" type="submit">送出</button>
			</form>
		</div>
	</div>
			
	<div class="row">
		<div class="col-xs-8 col-xs-offset-2">
			<h3>留言內容</h3>
			<div class="result">
			</div>
		</div>
	</div>			
</div>

在沒有樣板輔助的情況下,我們需要透過 jQuery 語法將 HTML 的字串組出來,因此所有的留言資料、排版,都必須寫在 jQuery 檔案裡。

顯示留言(Read)

顯示留言的邏輯大概是這樣:

  1. 讀取網頁
  2. 透過 jQuery 語法 (AJAX) 得知現在要撈出該 API 裡的資料
  3. 使用 GET 方法撈出資料
  4. 將撈出來的資料,利用 jQuery 改變 DOM 之後,秀在網頁上

轉換成語法則是:

$.ajax({
	url: ajax_url,
	type: 'GET',
	error: function(){
		console.log('error');
	},
	success: function(e){
		for(var i=0; i<e.length; i++) {
			$(".result").append(
				'<div class="full-msg" data-id="'+ e[i]._id +'">' +
				'<div>姓名:<div class="name">'+ e[i].username +'</div><div class="update" >更新留言</div><div class="del" >刪除留言</div></div>' +
				'<div>網站:<div class="url">'+ e[i].url +'</div></div>' +
				'<div>電子郵件:<div class="email">'+ e[i].email +'</div></div>' +
				'<div>標題:<div class="title">'+ e[i].title +'</div></div>' +
				'<div><div class="message">'+ e[i]. message +'</div></div>' +
				'</div>'
			);
		};
	}
});

ps. 我使用的 code highlight 會把span語法吃掉,所以替換為<div>表示。

$.ajax是 jQuery 包裝後的函式,因此他的格式都是固定的,我們只要把對應的資料寫進去,如果 url 跟 type(method) 正確,基本上資料都讀得到。

最後再透過 success 偵測資料成功被讀取後,應該要做的事情:
因此留言的資料非常多,所以我們要利用迴圈,將e物件的所有資料顯示出來,並透過append()把資料一筆一筆的接在後面。

組字串時把握兩個原則:

  • 當變數碰到 html 時,需要用+串接
  • 單引號用來包變數與 jQuery 語法,雙引號用來包 HTML 語法

組字串需要耐心跟細心,如果還是看不太懂他們的規則,我會建議先實作再透過開發者工具看 render 出來的 HTML 程式碼,相互對照會更加清楚他們的邏輯。

更新留言(Update)

更新留言的邏輯比較繁瑣一些,如果寫成文字大致如下:

  1. 點擊更新留言的按鈕
  2. 該篇留言會自動變成可編輯的表單,而且表單預設值是原本留言的內容
  3. 輸入完要更新的資料後,按下送出,表單會變回更新後的資料
  4. 如果按下取消,表單會變成原始資料,不會更新

因為有點複雜,所以我錄了一個 GIF 表示整個流程

轉為程式碼,也可以感受到他比 READ 還複雜許多,而且重點是這個程式碼我還沒寫完 哈哈哈 XDDDD

$(".result").on('click', '.update', function(){
	var fullMsg = $(this).closest('.full-msg'),
	    updateID = fullMsg.data('id'),
	    name = fullMsg.find('.name').text(),
	    url = fullMsg.find('.url').text(),
	    email = fullMsg.find('.email').text(),
	    title = fullMsg.find('.title').text(),
	    message = fullMsg.find('.message').text();
	var updateTemplate = 
		'<div>姓名:<input type="text" class="name" value="'+ name +'" required></div>' +
		'<div>網站:<input type="text" class="url" value="'+ url +'"></div>' +
		'<div>電子郵件:<input type="text" class="email" value="'+ email +'" required></div>' +
		'<div>標題:<input type="text" class="title" value="'+ title +'" required></div>' +
		'<div>內文:<textarea class="message" required>'+ message +'</textarea></div>' +
		'<div>送出取消</div>';
		
	fullMsg.html(updateTemplate);	
		
	$(".submit").on('click', function(){
		updateID = fullMsg.data('id');
		name = fullMsg.find('.name').val();
		url = fullMsg.find('.url').val();
		email = fullMsg.find('.email').val();
		title = fullMsg.find('.title').val();
		message = fullMsg.find('.message').val();
			
		$.ajax({
			url: ajax_url + updateID,
			type: 'PUT',
			data: {
				"title": title,
				"username": name,
				"message": message,
				"url": url,
				"email": email,
			},
			success: function(e) {
				console.log(e)
			}
		})
	});
	$(".cancel").on('click', function(){
		fullMsg.html()
	})
});

雖然沒有寫完,但是的確可以成功將留言更新,但更新後的樣式如果要用組字串的方式來寫,會太過於繁瑣,所以我後來採用 jQuery Template 實作(後面會再提到如何用 Template 改寫)。

但我們還是要簡單說一下這段程式碼,之後再把樣板加進來會比較好懂。

上述程式碼 highlight 的第 2 ~ 8 行(以下簡稱 A 段),以及 20 ~ 25 行(以下簡稱 B 段),乍看之下其實很類似,但兩個功能大不相同。

A 段代表的是上述邏輯的第二句話:留言會自動變成可編輯的表單,而且表單預設值是原本留言的內容。所以當我點下「更新按鈕」的時候,會利用 A 段將作者、標題、網址 … 等資料存到變數裡,這邊利用的是 DOM 的text()方法,接下來在updateTemplate 裡塞入表單元件,可以用value=""讓元件預設出現內容,所以在裡面塞入了各個變數。

而 B 段表示的,是當我更新完留言送出之後,會傳至 API 的實際內容。以name變數為例:name = fullMsg.find('.name').val();,將該表單元件的值存了起來,如果要得到元件的值,可以用val()方法。

最後再利用$.ajax加上put這個 type(method),將資料一個一個的傳回去。你可以利用 sucess 印出結果,如果傳送的物件是更新後的結果,表示程式正確。

如果參考我上面寫的文字流程,成功之後應該要讓畫面回到「顯示留言」的樣子,但是如果用這種方法寫,程式碼可能會又臭又長,所以才想用 template 改寫,因此斷尾了 XDDD。但大家有興趣,也可以試著想一下該怎麼把這個功能寫出來唷 🙂

刪除留言(Delete)

相較於更新,刪除真的是簡單許多,我們的 API 設計,是只要得到該留言的 ID 值,就能透過 ID 將留言刪除。

但根據我的 HTML 結構,我是將 ID 寫在最外面,刪除留言則是放在裡面:

<div class="full-msg" data-id="12345">
	<div>姓名:<div class="name">MUKI</div><div class="update" >更新留言</div><div class="del" >刪除留言</div></div>
	<div>網站:http://muki.tw</div>
	<div>電子郵件:muki@gmail.com</div>
	<div>標題:我是標題</div>
	<div>我是文章內容</div>
</div>

所以點擊「刪除留言」之後,該如何利用 jQuery 找到這一篇文章的 ID 呢?我使用了closest()方法,以「刪除留言」為中心點,找到離他最近的.full-msg

$(".result").on('click', '.del', function(){
	var fullMsg = $(this).closest('.full-msg'),
	    delID = fullMsg.data('id');
	$.ajax({
		url: ajax_url + delID,
		type: 'DELETE',
		error: function() {
			console.log('error');
		},
		success: function(e){
			console.log(e);
			fullMsg.fadeOut(800, function(){
				$(this).html('留言已刪除').fadeIn(800);
			});
		}
	});
})

如果成功刪除留言,必須要有一些簡單的回饋,讓使用者知道留言被刪除了 (就和更新留言是一樣的道理)。
只不過刪除比較簡單,我直接讓這一篇留言 fadeOut(),再秀出「留言已刪除」的字即可。


以上就是簡單的 CRUD 操作,希望對大家有所幫助。雖然語法看上去有點複雜,但其實觀念只有兩個,一是利用$.ajax操作 API,二是利用 jQuery 操作 DOM 讓使用者感受到回饋。

晚一點會更新如何使用樣板。我會以「更新留言」為例子,將他改寫成 template 的樣式,因為我們要的功能非常單純,所以我使用的是 jQuery Template,有興趣的朋友可以先閱讀他的官方文件。

to be continued…