iT邦幫忙

DAY 28
4

邊看邊學Groovy/Grails/Gradle系列 第 25

Grails-簡易Ajax Po文以及template fragment應用

昨天pagination失敗,還沒有時間研讀Grail API相關參數以及如何設計controller,今天先介紹Grails對Ajax的支援以及template fragment在列表文章的應用,可以上GSP的程式碼更簡潔,在Grails在寫出Ajax網頁還需javascript的library支援例如jquery(Grails預設已安裝jquery),搭配Grails tag即可做出有Ajax功能的網頁,今天將以之前posthistory.gsp為例
關於Ajax,首先我們必須認識幾個Grails Tags
1.

<g:javascript library="jquery">javascript code</g:javascript>

就是import jquery這個library,跟html不同的是grails是用plugin管理,而html則是要給檔案位置,另外tag間沒意外地可以寫javascript
2.
<g:submitToRemote url="" update="", onSuccess="", onLoading="", onComplete=""/>

此Tag就是ajax版的<g:submit>只是多了很多參數,來指定包裝後的xmlhttpresponse相關參數 ,url參數要指定action由哪一個controller負責,update參數指的是由controller回傳回來的參數要放在哪裡,onSuccess指Ajax動作完成後作什麼事,onLoading代表還未收到回應時作什麼事情,其餘以此類推

再來是template fragment,本例是將allPost交由_postentries.gsp來顯示,要注意template fragment網頁命名時前面要加底線,然後在posthistory.gsp使用<g:render>則只要指定postentries,不需要加底線

_postentries.gsp code的內容相當容易理解,只是把之前寫在posthistory allPosts裡的<g:each>搬到_postentries.gsp而已,code如下

<div class="postEntry">
    <div class="postText">${post.content}</div>
    <div class="postDate">${post.dateCreated}/></div>
</div>

接下來接先po上Ajax版的 posthistory.gsp

<%@ page contentType="text/html;charset=UTF-8"%>


<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="layout" content="main" />
<g:javascript library="jquery" />
<g:javascript>
            function clearPost(e) {
                $('#postContent').text('');
            }
            function showSpinner(visible) {
                if (visible) $('#spinner').show();
                else $('#spinner').hide();
            }
</g:javascript>
<title>All Posts for ${ user.userId }</title>


	<div class="body">

		<h3>
			Hi!
			${ user.userId }, what is in you mind right now?
		</h3>
		<g:if test="${flash.message}">
			<font size=3 color=#3bb11d> 
			<strong> 
			<u> ${flash.message}</u>
			</strong>
			</font>
		</g:if>
		<p>
			<g:form action="ajaxAdd">
				<g:textArea id='postContent' name="content" rows="3" cols="100" />
				<br/>
				<g:submitToRemote value="Post"
					url="[controller: 'post', action: 'addPostAjax']" update="allPosts"
					onSuccess="clearPost(e)" onLoading="showSpinner(true)"
					onComplete="showSpinner(false)" />
				
				<g:img id="spinner" style="display: none" uri="/images/spinner.gif" />
			</g:form>
		</p>

		<br />
		<hr size=1 align=center width=100%>
		<div class="allPosts">
			<g:render template="postentries" collection="${ user.posts}" var="post"/>
		</div>

	</div>

<g:submitToRemote>指定由PostController中addPostAjax來處理Ajax的request,得到的post結果將update到allPosts,onSuccess時用javascript function clearPost(e)清除<g:textArea>, onLoading時show spinner.gif表示Ajax動作中讓user不至於以為網頁沒動作,onComplete時就把spinner image hide

接下來必須新增addPostAjax code如下:

def addPostAjax(String content) {
        try {
            def newPost = postService.createPost(session.user.userId, content)
			//利用PostService新增一個post
            def recentPosts = Post.findAllByUser(session.user, 
				[sort: "dateCreated", order: "desc", max: 20])
			//搜尋所有該user所有的post並依時間排序
            render template: "postentries", collection: recentPosts, var: "post"
			//render template fragment並將recentPost即所有的Post當作變數傳回
        } catch (PostException pe) {
            render {
                div(class:"errors", pe.message)
            }//把錯誤訊息render到div class="errors"
        }
    }

run-app即可成功顯示網頁

Post in progress, spinner image show....


上一篇
Grails-UrlMapping設定、Grails Tag以及Grails layout(sitemesh)介紹
下一篇
Grails-簡易Pagination Demo以及email support in grails
系列文
邊看邊學Groovy/Grails/Gradle27

1 則留言

我要留言

立即登入留言