寫在前面
ionic 是一個用來快速開發跨平台應用的架構,亮點不少:
-
學習成本低
對前端開發人員來說,學習成本不是很高,如果有接觸過 angular ,就幾乎沒有什麼學習成本了
-
簡單易用
強大的CLI, start -> platform -> serve -> build -> emulate -> run ,全套服務命令列完成,不用寫設定檔,不用F5
-
組件多而強大
提供了很多強大的現成組件,很容易實現流行的互動效果,比如下拉重新整理( ion-refresher )、上拉載入/瀑布流( ion-infinite-scroll )、tabs( ion-tabs )、側邊欄菜單( ion-side-menu )等等,只需要寫一點點代碼,就能實現這些流行效果,比native開發速度快太多了
-
支援cordova外掛程式
開啟了這扇門,意味著我們可以使用大量的原生功能,比如調用相機拍照、響應返回按鈕、打電話發簡訊發郵件……都只要幾行代碼就能搞定
-
更新速度快
2015/11/1是v1.1.0,現在(2016/1/9)已經是v1.2.4了,快速更新意味著有人維護,bug能被迅速修複
當然,也有缺陷,否則就沒有這篇筆記了,如下:
-
新版本不完全向後相容
不相容沒關係,給個詳細文檔說明下也行啊,沒有
-
bug難以定位
angular+cordova+ionic+javascript,發現問題後,很難確定是哪塊的問題
-
效能最佳化難
動畫卡頓,低端機體驗更差,而最佳化措施一般都是建議少用動畫少用陰影少用漸層……但是,不用實在太醜,而且與native應用體驗差太多
-
其它
奇奇怪怪的問題找不到答案,大半夜的翻stackoverflow……
一.jsonp跨域,php服務怎麼寫
P.S.這是angular的問題,當時沒整理筆記,後來就忘記了遇到過這麼個問題
angular的$http可以發送jsonp請求,用法類似於jQuery,如下:
// 請求資料$http.jsonp(sUrl).success(function(res){ // ...}).error(function(err){ // ...});
sUrl 有特殊要求,必須帶上 callback 參數,而且參數值 只能 是 JSON_CALLBACK ,angular文檔:
Relative or absolute URL specifying the destination of the request. The name of the callback should be the string JSON_CALLBACK.
例如:
var sUrl = http://www.ayqy.net/app/rsshelper/index.php?callback=JSON_CALLBACK
而問題是:php服務怎麼寫?直接返回用 JSON_CALLBACK() 包裹的json資料?
不對,因為真正請求的url中 callback !== JSON_CALLBACK ,被angular 偷偷 (文檔沒有說明)替換掉了,所以後台需要這樣寫:
當然,這是get的情況,比較簡單,如果是post,還需要通過別的方式取 callback ,完整例子如下:
二.ion-content的阻尼回彈效果沒了
ionic v1.2取消了 ion-content 預設的阻尼回彈效果,明明一模一樣的代碼,就是沒有回彈效果,後來發現是版本更新的鍋,翻了很久後,在 官方部落格 的 評論 裡找到了答案:
Great news, thank you! It seems that the “has-bouncing=’true'” does not work with the native scroll, is it correct? I managed though to have it again by going to back go js scroll (overflow-scroll=”false”)
I only checked in the browser so if any one can confirm that with native scrolling removes bouncing that would be great.
I need this feature for a custom ‘pull refresh’ method I had.
也就是說,v1.2之後想要有阻尼回彈效果,需要這麼做:
三.多個view之間的資料共用
也就是多個controller之間的資料共用(一般不同view對應不同controller)問題,當然,最簡單的方法是用全域變數( $rootScope ),但這樣不好,更合理的方式是自己寫個 service 或者 factory ,提供資料存取介面,在需要的地方依賴注入即可,比如:
.service('DataServ', ['$http', 'UIServ', function($http, UIServ) { // ... // 字典 var oDir = { // key: value }; function save(val) { var sKey = Date.now() + ''; oDir[sKey] = val; return sKey; } function get(sKey) { return oDir[sKey]; } return { // ... save: save, get: get };}]);
然後通過url傳遞 sKey 即可實現資料共用,很乾淨
四.通知視圖更新
在模板中寫好了資料展示,但如果開啟頁面後資料還沒到,模板解析完了,由於沒有資料顯示空白頁,過了一會兒資料到了,發現視圖沒有更新,仍然是一片空白,比如:
{{data}}
// jsapp.controller('MainCtrl', ['$scope', 'DataServ', function($scope, DataServ) { // ... setTimeout(function() { // ... $scope.data = 'data'; })}]);
因為給data賦值的操作跑到了controller範圍外,此時需要手動通知視圖更新,如下:
// ...$scope.data = 'data';$scope.$apply();
當然,一般不需要手動通知,即便是非同步返回的資料,因為這裡只與範圍有關,總之,如果發現視圖需要手動更新,添上 $apply 就好了
五.php原生xml擴充如何擷取 裡的內容
rss格式中會有 標籤,直接取 content 取不到,需要特殊的方式:
$content = (string)$item->children("content", true);// $encodedContent = $content->encoded;// $content->encoded返迴轉義過的html,比如把&轉成&,一般用於直接展示
當然,前提是使用原生xml擴充( $xml = simplexml_load_file($url); )解析xml才會遇到這個問題,更多用法請查看 php – How to parse CDATA HTML-content of XML using SimpleXML? – Stack Overflow
六.在瀏覽器中開啟外部頁面
需要使用一個cordova外掛程式,cd進專案檔夾,然後:
ionic plugin add cordova-plugin-inappbrowser
安裝完成後就可以調用了,不用修改設定檔,不用引入其他js,如下:
// openInBrowserwindow.open(‘http://example.com’, ‘_system’); Loads in the system browserwindow.open(‘http://example.com’, ‘_blank’); Loads in the InAppBrowserwindow.open(‘http://example.com’, ‘_blank’, ‘location=no’); Loads in the InAppBrowser with no location barwindow.open(‘http://example.com’, ‘_self’); Loads in the Cordova web view// testwindow.open(url, '_system'); // 系統預設瀏覽器// window.open(url, '_blank'); // 很醜的安卓內建瀏覽器// window.open(url, '_self'); // 同上
一般都用 _system ,另外兩個實在太醜,更多內容請查看 Cordova InAppBrowser Plugin Example using ionic framework
七.splash screen黑屏白屏
P.S.黑屏白屏其實是同一個問題,但這個問題相當難解決,筆者花了快1天才搞定
ionic預設整合了 splashscreen 外掛程式,這個cordova外掛程式效果不是很完美,預設配置只在首次開啟app時顯示splash screen,但實際效果是:
When the app starts the splash screen shows for a few seconds as expected, and then the screen goes black for @1 second and then white for @2 seconds and then the main app page appears.
Is there any way to prevent the black and white pages appearing? I read somewhere that a black page appears when there is no splash page but I do have a splash page and it appears fine.
在 stackoverflow 找到了這個問題描述,簡直太貼切了,但是單靠問題下面的回答無法解決白屏問題,還需要改設定檔
最初發現的現象是黑屏(把上面英文描述裡的white換成黑),後來找到了原因:主視圖容器 ion-nav-view 是空的,而它的背景色是 #000 ,所以修複方法是給裡面塞個 ion-view :
或者添css,把 ion-nav-view 的背景色改成白色。但問題還沒解決,黑屏問題變成白屏問題了,解決方案比較麻煩
-
把splashscreen外掛程式降級到v2.0.0
v2.0.0之後的版本有bug,目前(2016/1/9)內建的版本是v3.0.0。先cd到專案檔夾,然後命令列:
// 刪掉現有版本cordova plugin rm cordova-plugin-inappbrowser// 安裝v2.0.0cordova plugin add cordova-plugin-inappbrowser
-
改設定檔MyApp/config.xml
取消自動隱藏(改為代碼控制隱藏),把期間改為較大的值(10秒),設定每次開啟應用都顯示splash screen
P.S.預設只有 SplashScreen 和 SplashScreenDelay ,需要把其它的( SplashMaintainAspectRatio 可選)都添上
-
改app.js
手動隱藏splash screen,在run裡面添上
.run(['$rootScope', function($rootScope) { // init // $rootScope.isLoading = false; // hide splash immediately if(navigator && navigator.splashscreen) { navigator.splashscreen.hide(); } });}]) 這樣就好了,不要延時調用hide,否則仍然會出現白屏(有些解決方案要求$timeout 50毫秒hide,仍然會出現白屏,不要這樣做)
最怨念的問題結束了,看似簡單的功能,想要有 完美的原生體驗 卻很難,奇奇怪怪的問題很難解決,目前可行的解決方案可能過段時間就不行了,可以查看 White page showing after splash screen before app load 感受一下
八.安卓版本簽名發布
各種簽名方法都過時了,目前(2016/1/9)可以用的簽名方法如下:
-
在MyApp\platforms\android建立keystore
具體步驟請查看: Ionic toturial for building a release.apk
-
建立release-signing.properties檔案
具體步驟請查看: How to automatically sign your Android apk using Ionic framework and Crosswalk
-
build
cd到專案檔夾,然後命令列 ionic build --release android ,成功後會產生2個東西,在MyApp\platforms\android\build\outputs\apk下,分別是android-armv7-release.apk和android-x86-release.apk,一般平板和PC用x86,手機用arm7,如果要上傳google play的話,2個都要傳,下載時有自動識別
至於crosswalk,提供了chrome核心,能讓低端機支援高端東西,但會讓apk 變大很多 (3.5M->23M),添上crosswalk後,感覺。。。嗯,變卡了,但為了支援低端機使用者,一般都會添上crosswork
九.總結
怎麼說呢,快速開發很棒,後遺症很傷。
筆者從1月3號開始搞,1月8號中午release v1.0.0,靚照如下:
rsshelper
rsshelper
看著還不錯吧,非賣品,不贈送~