DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> HTML基礎知識 >> HTML5詳解 >> Ember.js + jQuery Mobile + PhoneGap HTML5 and CSS3 開發
Ember.js + jQuery Mobile + PhoneGap HTML5 and CSS3 開發
編輯:HTML5詳解     

隨著Html 5的興起,基於此的項目也越來越的多,因而出現了很多MVC框架,如:Backbone.js、Ember.js、Angular.JS等,此系列將闡述這些框架在代碼層面的區別,希望可以給初學者一些思路。

本文將介紹Ember.JS構建基於jQuery Mobile的PhoneGap項目(Hybird App)。

功能介紹

使用Ember.JS + jQuery Mobile + PhoneGap構建一個Hybird App項目,命名為Adobe Reader,具有如下功能:

  1. 讀取http://feeds.adobe.com/xml/rss.cfm的數據(XML源)。
  2. 將XML的內容以列表的形式展示出來。
  3. 點擊任意列表項目(Item),可以跳轉到相應地址。

項目依賴

  1. jQuery(1.8.2版)
    • 下載地址:http://jquery.com
    • 替代JavaScript語法。
  2. jQuery Mobile(1.2.0 Final版)
    • 下載地址:http://www.jquerymobile.com
    • 實現UI構建。
  3. Ember.JS(0.9.8.1版)
    • 下載地址:http://www.emberJS.com/
    • 實現MVC架構。
  4. Ember-bridge-jqm(0.1)
    • 下載地址:https://github.com/kenshin/ember-bridge-jqm
    • Ember.JS無法直接與jQuery Mobile搭配,所以需要ember-bridge-jqm來“代理”。
    • 代碼基於https://github.com/LuisSala/emberJS-jqm和https://github.com/tolbard/ember-moving修改。
  5. XML2JSon
    • 下載地址:請看范例文件
    • XML轉JSON的jQuery插件。
  6. PhoneGap(2.0.0 版)
    • 下載地址:http://www.phonegap.com
    • 打包App時需要。

范例文件

  1. 附件

通過本文將學會

  1. 理解Ember.JS的MVC結構特點。
  2. 掌握Ember.JS與jQuery Mobile的特殊寫法(ember-bridge-jqm的運用)
  3. 掌握Ember.JS的特色功能:UI Binding。

項目截圖

Figure1

工程結構

Figure2

  1. common:共同的JS類庫,如jQuery、jQuery Plugin等。
  2. ember:Ember.JS相關類庫。
  3. Javascripts:Ember.JS對應MVC結構的JavaScript代碼。
  4. jqm:jQuery Mobile相關類庫。
  5. phonegap:PhoneGap相關類庫。
  6. stylesheets:CSS文件。

項目架構

Figure3

代碼分析

下面將展示Adobe Reader的關鍵代碼,並分別介紹Ember.JS中M(Model)V(VIEw)C(Controller)代碼特點、UI Binding的實現等功能。

Application(應用程序入口)

App = Em.Application.create();

與所有的Ember.JS App都是一樣,首先要建立一個Application

VIEws(視圖)

App.PageView = Mov.PageVIEw.extend();

上面的代碼與通常的Ember.JS App在VIEw(視圖)層的繼承不太一樣,主要區別在於全部的VIEw(視圖)都繼承自Mov,那麼Mov是什麼?

Mov定義在ember-bridge-jqm中,可以在assetswwwemberember-bridge-jqm.js中找到。為什麼Ember.JS不能直接與jQuery Mobile一起使用,而非要一個“代理”才行?

因為Ember.JS在實現的時候會修改Html代碼,因此具有“侵入性”。眾所周知jQuery Mobile也是一個“侵入性”很強的類庫,例如:它會把 <div data-role="header"></div>這樣的代碼“改為”<div data-role="header" class="ui-header ui-bar-a" role="banner"></div>。當這兩種“侵入性”的類庫放在一起,就會出現各種未知錯誤,所以才有ember-bridge-jqm.JS這樣的“代理”類庫。

通常一個典型的jQuery Mobile具有如下結構:

<div data-role="page"> <div data-role="header"></div> <div data-role="content"></div> <div data-role="footer"></div> </div>

加入ember-bridge-jqm.JS後,Html結構可以直接用JavaScript的方式實現:

App.PageView = Mov.PageView.extend(); App.HeaderView = Mov.HeaderView.extend(); App.FooterView = Mov.FooterView.extend(); App.ContentView = Mov.ContentVIEw.extend();

注:上述代碼分別實現了jQuery Mobile的 "page" "header" "content" "footer"視圖。

以上就是VIEw(視圖)層的關鍵代碼,主要負責實現jQuery Mobile的結構,接下來看一下Model(模型)的代碼。

Model(模型)

定義如下數據結構(value Object)

App.Articles = Ember.Object.extend({ title : null, link : null, desc : null, creator : null, date : null });

上述結構與RSS源的XML節點保持一致。由於需要處理XML,因此增加一個叫做ServicesModel的函數,功能是讀取XML,代碼如下:

App.ServicesModel = function( target, url ) { $.AJax({ type : "GET", url : url, success: function( XML ) { //get json var json = $.xml2JSon( XML ); //call json2obj App.Json2Obj( target, JSon.item ); } }); }

ServicesModel具有如下功能:

  1. 使用AJax方式讀取RSS源。
  2. 將讀取的XML轉化為JSON對象。
  3. 調用App.JSon2Obj。

再看一下JSon2Obj的實現:

App.JSon2Obj = function( target, tmp ) { target.set( 'content', [] ); $( tmp ).each( function( index, value ) { var tmp = App.Articles.create({ title : value.title, link : value.link, desc : value.description, creator : value.creator, date : value.date, }); target.pushObject( tmp ); }); }

JSon2Obj具有如下功能:

  1. 循環遍歷傳入的JSON對象,並將遍歷後的內容保存到VO(App.Articles.create())
  2. 通過pushObject將每個遍歷後的App.Articles(VO)保存到target(傳入的參數)。

注:pushObject是Ember.JS方法,與Ember.ArrayController一同使用,將循環遍歷(each)後的VOApp.Articles)保存到(pushObjectArrayControllercontent中。

以上就是Model(模型)層的關鍵代碼,主要負責實現XML的讀取、解析和保存,接下來看一下Controller(控制器)的代碼。

Controller(控制器)

 

App.getArticlesController = Ember.ArrayController.create({ content : [], init : function () { //call services model App.ServicesModel( this, "http://feeds.adobe.com/XML/rss.cfm?query=byMostRecent&languages=5" ); } });

getArticlesController具有如下功能:

  1. 實現Ember.JS的控制器App.getArticlesController = Ember.ArrayController.create();
  2. 調用Model層的ServicesModel,並傳入兩個參數:
    • this(供使用pushObject方法)
    • URL(傳入解析用的RSS地址)

總結

以上就是JavaScript端MVC各層的關鍵代碼,代碼的實現與其他框架並無太大的區別,需要注意的是如何使用Ember.JS方式實現MVC結構的寫法:

  1. Model:Ember.Object.extend();
  2. View:Mov.PageVIEw.extend();
  3. Controller:Ember.ArrayController.create();

接下來看一下Html端的Ember.js寫法,並展示Ember.JS有別於其他MVC框架的特點:UI Binding

Html端相關類庫的引入

<head>標簽內:

<!-- jquery mobile --> <link rel="stylesheet" href="jqm/jquery.mobile-1.2.0.min.css" /> <!-- customer --> <link rel="stylesheet" href="stylesheets/style.CSS" />

<body>標簽內:

<!-- common --> <script src="common/jquery-1.8.2.min.JS"></script> <script src="common/jquery.XML2json.js"></script> <!-- jquery mobile --> <script src="jqm/jquery.mobile-1.2.0.min.js"></script> <!-- ember.js --> <script src="ember/ember-0.9.8.1.min.js"></script> <script src="ember/ember-bridge-jqm.JS"></script> <!-- customer --> <script src="Javascripts/app.js"></script> <!-- phonegap --> <script src="phonegap/cordova-2.0.0.JS"></script>

注:之所以要把<script>放到<body>標簽中主要基於加快加載速度的考慮。

jQuery Mobile結構的實現(ember-bridge-jqm的運用)

<body>中加入如下代碼:

<script type="text/x-handlebars" data-template-name="main"></script> <div data-role="page"></div>

注:data-template-name的值一定要設定為"main"

在Javascripts/app.JS的VIEw(視圖)層中加入如下代碼:

App.PageView = Mov.PageView.extend({ templateName:'main', id: 'page-vIEw', didInsertElement: function() { $.mobile.changePage(this.$()); } });

注:App.PageVIEw.templateNameid的值一定按照上述設定。

在Html端加入如下代碼:

{{#view App.HeaderView}} ..... {{/view}} {{#view App.ContentView}} ..... {{/view}} {{#view App.FooterView}} ..... {{/vIEw}}

這些代碼的結構等價於jQuery Mobile的結構:

<div data-role="header"></div> <div data-role="content"></div> <div data-role="footer"></div>

注:App.HeaderVIEwApp.ContentVIEwApp.FooterVIEw定義在Javascripts/app.JS中,{{}}是模版引擎(Handlebars.JS)的語法。

ListvIEw(UI Binding)的實現

在Javascripts/app.JS新增一個VIEw(視圖)層,命名為ListVIEw

App.ListView = Mov.ListVIEw.extend();

在Html端加入如下代碼:(重點)

{{#view App.ContentView}} {{#collection App.ListVIEw contentBinding="App.getArticlesController"}} <a {{ bindAttr href="content.link" }} data-AJax="false" > <h3>{{ content.title }}</h3> <p>via {{ content.creator }}</p> <p>{{{ content.desc }}}</p> </a> {{/collection}} {{/vIEw}}

具有如下功能:

  1. 定義了一個ContentVIEw,並在其中加入ListVIEw
  2. ListVIEwcontentBinding設定為App.getArticlesController,由於ListVIEw是一個數組結構(App.getArticlesController = Ember.ArrayController.create();)所以使用了關鍵字Collection,而非VIEw。
  3. content.title、content.creator、content.desc來源於App.getArticlesController.content,而App.getArticlesController.content的值是調用pushObject而來,通過App.JSon2Obj的代碼可知,content.title、content.creator、content.desc分別存儲了解析XML後的App.Articles(Value Object)值。

注:bindAttr href="content.link"並沒有寫成:<a href="{{ content.link }}">,是因為Ember.JS在“注入”代碼的時候,會生成<script id="metamorph-0-start" type="text/x-placeholder">XXX</script>這樣的結構,所以在設定href時不能直接寫{{ content.link }},而是使用bindAttr方式。

總結

Embe.JS通過CollectionpushObject以及模版引擎(Handlebars.JS)來實現。

PhoneGap

由於PhoneGap只起到打包(android App)作用,並沒有使用PhoneGap的相關功能,因此無需引入<script src="phonegap/cordova-2.0.0.JS"></script>,直接打包即可,PhoneGap的過程略去。

結論

  1. Ember.JS與jQuery Mobile都是具有“侵入性”的框架,所以盡量不要放在一起使用,如在一起使用,需要“代理”方式(ember-bridge-jqm)。
  2. 由於Ember.JS與jQuery Mobile的“不兼容性”,所以在編寫jQuery Mobile組件的時候,無法直接寫到Html中,而是寫到Handlebars.JS的模版裡面。(針對動態生成組件而言)
  3. Ember.JS搭配的UI庫盡量不具有“侵入性”,例如:Bootstrap等。
  4. Ember.JS最強大的地方(之一)在於UI Binding。(通過CollectionpushObject以及模版引擎(Handlebars.JS)實現)
  5. 如果你對Cocoa熟悉的話,你會在Ember.JS身上找到它的身影。
  6. 如果你對Flex熟悉的話,你會找到久違的“dataProvide”和“itemrender”屬性。
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved