天天看點

使用JS模闆引擎實作前後端分離

前言

在web應用開發的架構中,普遍都會使用MVC設計來分離業務邏輯和視圖元素,最終在視圖部分使用JSP/Velocity/freemarker等技術把動态内容轉換為HTML靜态頁面給浏覽器顯示,如下圖所示

使用JS模闆引擎實作前後端分離

在這種開發模式下前端寫好靜态demo,後端翻譯成JSP/Velocity/freemarker模版,這種模式的問題就不說了,前端需要依賴後端資料才能測試,如果讓前端人員基于後端環境開發也很痛苦,配置安裝使用都很麻煩。另外,後端也沒法擺脫對展現的強關注,進而專心于業務邏輯層的開發。

之是以産生這些問題,我認為傳統的MVC架構本質其實是一個服務端的MVC架構,雖然MVC設計模式裡的V即View視圖層是想把界面開發工作專業化,讓界面設計人員能專心于界面開發,但是傳統的MVC架構下的View層的本質卻是一個不折不扣的服務端技術。

向前端演進

我認為要解決這個問題最主要就是把頁面渲染工作從伺服器分離出來,因為渲染這塊工作,對于前端開發者的日常工作來說,佔了非常大的比例,也是最容易與後端開發糾結不清的地方。

回首過去前端技術發展的這幾年, View 這個層面的工作,經過了許多次的變革,像是:

    1.   Form Submit 全頁重新整理 => AJAX局部重新整理

    2.   服務端續染 + MVC => 用戶端渲染 + MVC

    3.   傳統換頁跳轉 => 單頁面應用

可以觀察到在這幾年,大家都傾向将 渲染 這件事,從伺服器端端移向了浏覽器端。

而伺服器端則專注于 服務化 ,提供資料接口。

本文

當渲染工作由服務端轉向浏覽器端後,就變成了下圖這樣的設計

使用JS模闆引擎實作前後端分離

服務端的MVC并不用取消,隻是view的工作由頁面渲染改為提供資料接口,同時在前端引入MVC設計,由前端View負責把資料渲染成最終頁面。

好了,差不多進入正題了(-_-!),其實本文并不是講解前端MVC設計,而是講前端MVC設計過程中一個重要的技術問題:如何在前端渲染頁面?

不過在講前端渲染技術之前先了解下前端渲染的好處和壞處,并不是所有情況都适合在前端渲染,大家要根據項目實際情況取舍

浏覽器端渲染的好處

浏覽器端渲染的好處,我們都很清楚,像是

    1.    擺脫業務邏輯與呈現邏輯在Java模版引擎中的耦合與混亂。

    2.    針對多終端應用,更容易以接口化的形式。在浏覽器端搭配不同的模版,呈現不同的應用。

    3.    頁面呈現本來就不僅是html,在前端的渲染可以更輕易的以元件化形式 (html + js + css)提供功能,使得前端元件不需依賴于服務端産生的html結構。

    4.    脫離對于後端開發、發佈流程的依賴。

    5.   友善聯調。

浏覽器端渲染造成的壞處

但是在享受好處的同時,我們同樣的也面臨了 浏覽器端渲染 所帶來的壞處,像是:

    1.    模版分離在不同的庫。有的模版放在服務端 (JAVA),而有的放在浏覽器端 (JS)。前後端模版語言不相通。

    2.    需要等待所有模版與元件在浏覽器端載入完成後才能開始渲染,無法即開即看。

    3.   首次進入會有白屏等待渲染的時間,不利于使用者體驗

    4.    開發單頁面應用時,前端Route與伺服器端Route不比對,處理起來很麻煩。

    5.    重要内容都在前端組裝,不利于SEO

JavaScript模闆引擎

OK,終于進入正題了((@﹏@)~),前端渲染目前最好的方法就是使用js模闆引擎,

什麼是javascript模闆引擎?

javascript模闆引擎可以用來幫助開發人員有效的組織和分離前端頁面代碼中的顯示層和資料層兩個部分。這裡我們主要集中在在前端頁面内容的展示方面。如果你接觸過後端相關開發的話,基本的思路和目地是一緻的。具體這裡我們舉個簡單的例子:

如果你需要将一個來自背景的JSON資料對象轉化成頁面顯示内容的話,通常使用如下方式(具體示範使用jQuery):

var siteinfo={sitename:‘terry li’, siteurl:‘gbin1.com’};

var userwrapper = $(‘<ul>’)

.append(‘<li>’ + siteinfo.sitename+ ‘</li>’)

.append(‘<li>’ + siteinfo.siteurl + ‘</li>’);

var html = userwrapper.html();

以上代碼非常簡單,我們将得到的siteinfo對象直接使用字元串拼接來轉化成頁面需要展示的html标簽。這裡我們使用一個ul元素來展示站點的全部相關資訊。

從代碼本身來講,無可厚非,大部分人對于簡單的頁面Html生成基本都使用這種方法,而比較現實的狀況是,很多的前端開發人員都習慣這些書寫代碼,因為思路簡單并且直接,當然,包括我本人。對于代碼層次和資料結構簡答的項目來說,這樣的寫法非常易于了解。但是如果這個JSON對象屬性内容豐富複雜,并且前台顯示邏輯稍微複雜一點兒的話,我相信,使用這種字元串連接配接的方式,将絕對會讓閱讀維護代碼的同僚抓狂。

而javascript模闆引擎恰恰就是為了幫助我們有效的組織資料及其展示内容而出現的。和其它的模闆使用方式一樣,你需要做如下兩個事情:

1. 建立展示模闆

2. 将資料解析到模闆中

    例如上面字元串組裝如果用js模闆寫的話是這樣(示範使用underscore模闆)

var siteinfo={sitename:‘terry li’, siteurl:‘gbin1.com’};

var userwrapper = ‘<ul><li>{{= sitename }}</li><li>{{ =siteurl }}</li><ul>’;

var render = _.template(userwrapper);

var html = render(siteinfo);

    是不是很清晰,特别當頁面内容灰常豐富時你就知道這種方式有多好了。

模闆引擎的選擇

目前網上開源的模闆引擎真是百花齊放,太多選擇了,國内的話推薦百度的baiduTemplate,阿裡巴巴的kissyTemlate,騰訊的artTemplate,國外推薦的就有Mustache,jade,Handlebars ,EJS,doT.js,underscore.js等。

我目前在項目中使用的是underscore.js,因為模闆隻是underscore的一個小功能而已,他還提供了很多其他實用的功能作為對jquery的補充,比較适合企業内網的應用。另外underscore模闆使用的是JavaScript原生文法,對于初學上手快,如果熟悉JavaScript那其實也就幾分鐘學完了。

如果項目中的人員都已經熟悉和習慣了用js模闆,那麼這時推薦用支援簡潔文法的模闆引擎(其實大部分模闆都是使用簡潔文法),或者有些同時支援簡潔文法和原生文法,例如artTemplate.js

例如下面示範artTemplate的簡潔文法和原生文法

簡潔文法

推薦使用,文法簡單實用,利于讀寫。

原生文法

最佳實踐

大部分模闆語言都把{{ }}或者<% %>裡面的内容當做模闆語言進行渲染,一般也會有自定義的功能可以更改這個預設符号。另外由于<% %>符号正好和JSP沖突,是以在JSP中可以使用{{}}代替

案例示範

下面我用内網應用中最常見的分頁表格示範具體在項目中的應用

1、首先我們需要确定頁面中哪些部分為動态内容,例如下圖打了紅框的部分為表格中的動态内容,分别為表格内容和分頁資訊;

使用JS模闆引擎實作前後端分離

 2、然後我們用JavaScript模闆改寫動态内容部分(示範使用underscore引擎),看下圖

使用JS模闆引擎實作前後端分離

l  使用<script type="underscore/table">标簽表示裡面的内容為動态模闆

l  第一個模闆for循環content資料清單,然後輸出裡面的值

l  第二個模闆直接輸出分頁資訊

3、接着開發分頁查詢資料接口,接口傳回json格式的資料,資料如下圖 

使用JS模闆引擎實作前後端分離

4、最後編寫查詢按鈕的js控制,調接口查詢,然後在回調方法裡面調用模闆渲染,例如用jquery類似這樣寫

//jquery查詢

$.getJSON(

    'http://localhost:8080/test/query.action',

    function(data,status){

        //擷取模闆

        $('script type="text/javascript"').each(function(){

           var source = $(this).html();//取模闆内容

           var render = _.template(source);

           var html = render(data);//渲染

           $(this).parent().html(html);//把渲染結果加入頁面

        })

    }

);