ionic开发跨平台App常见问题

WBOY
Freigeben: 2016-06-20 12:40:54
Original
1346 Leute haben es durchsucht

写在前面

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){    // ...});
Nach dem Login kopieren

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
Nach dem Login kopieren

而问题是:php服务怎么写?直接返回用 JSON_CALLBACK() 包裹的json数据?

不对,因为真正请求的url中 callback !== JSON_CALLBACK ,被angular 偷偷 (文档没有说明)替换掉了,所以后台需要这样写:

<?phpif (strpos($_SERVER["REQUEST_URI"], 'callback')) {    $res = json_encode($res);    // echo $_SERVER["REQUEST_URI"];    // /angular/test/http/main.php?callback=angular.callbacks._0    // $res = 'JSON_CALLBACK('.$res.')';    // 错的    $res = $_GET['callback'].'('.$res.')';}?>
Nach dem Login kopieren

当然,这是get的情况,比较简单,如果是post,还需要通过别的方式取 callback ,完整例子如下:

<?php// getif ($_SERVER['REQUEST_METHOD'] === 'GET') {    $res = '{';    // arg    if (isset($_GET['arg'])) {        $res .= '"arg": "'.$_GET['arg'].'", ';    }    // method    if (strpos($_SERVER["REQUEST_URI"], 'callback')) {        // echo $_SERVER["REQUEST_URI"];        // /angular/test/http/main.php?callback=angular.callbacks._0        $res .= '"arg": "'.$_GET['arg'].'", ';        $res .= '"method": "jsonp"}';        // $res = 'JSON_CALLBACK('.$res.')';        // 错的        $res = $_GET['callback'].'('.$res.')';    }    else {        $res .= '"method": "get"}';    }    echo $res;}// postelse if ($_SERVER['REQUEST_METHOD'] === 'POST') {    // 直接拿拿不到,因为传过来的是json串    // echo $_POST['arg'];    $jsonArg = file_get_contents('php://input');    if (isset($jsonArg)) {        echo substr($jsonArg, 0, strlen($jsonArg) - 1).', "method": "post"}';    }    else {        echo '{"method": "post"}';    }}?>
Nach dem Login kopieren

二.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之后想要有阻尼回弹效果,需要这么做:

<ion-content overflow-scroll="false" has-bouncing="true"></ion-content>
Nach dem Login kopieren

三.多个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    };}]);
Nach dem Login kopieren

然后通过url传递 sKey 即可实现数据共享,很干净

四.通知视图更新

在模板中写好了数据展示,但如果打开页面后数据还没到,模板解析完了,由于没有数据显示空白页,过了一会儿数据到了,发现视图没有更新,仍然是一片空白,比如:

<!-- html --><p ng-cloak>{{data}}</p>// jsapp.controller('MainCtrl', ['$scope', 'DataServ', function($scope, DataServ) {    // ...    setTimeout(function() {        // ...        $scope.data = 'data';    })}]);
Nach dem Login kopieren

因为给data赋值的操作跑到了controller作用域外,此时需要手动通知视图更新,如下:

// ...$scope.data = 'data';$scope.$apply();
Nach dem Login kopieren

当然,一般不需要手动通知,即便是异步返回的数据,因为这里只与作用域有关,总之,如果发现视图需要手动更新,添上 $apply 就好了

五.php原生xml扩展如何获取 里的内容

rss格式中会有 标签,直接取 content 取不到,需要特殊的方式:

$content = (string)$item->children("content", true);// $encodedContent = $content->encoded;// $content->encoded返回转义过的html,比如把&转成&,一般用于<pre class="brush:php;toolbar:false">直接展示
Nach dem Login kopieren

当然,前提是使用原生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
Nach dem Login kopieren

安装完成后就可以调用了,不用修改配置文件,不用引入其他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');  // 同上
Nach dem Login kopieren

一般都用 _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 :

<!-- 内容 --><ion-nav-view>    <!-- 防止启动时黑屏 -->    <ion-view></ion-view></ion-nav-view>
Nach dem Login kopieren

或者添css,把 ion-nav-view 的背景色改成白色。但问题还没解决,黑屏问题变成白屏问题了,解决方案比较麻烦

  1. 把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
    Nach dem Login kopieren
  2. 改配置文件MyApp/config.xml

    <preference name="SplashScreen" value="screen"/><preference name="AutoHideSplashScreen" value="false"/><preference name="auto-hide-splash-screen" value="false"/><preference name="ShowSplashScreenSpinner" value="false"/><preference name="SplashMaintainAspectRatio" value="true" /><preference name="SplashShowOnlyFirstTime" value="false"/><preference name="SplashScreenDelay" value="10000"/>
    Nach dem Login kopieren

    取消自动隐藏(改为代码控制隐藏),把持续时间改为较大的值(10秒),设置每次打开应用都显示splash screen

    P.S.默认只有 SplashScreen 和 SplashScreenDelay ,需要把其它的( SplashMaintainAspectRatio 可选)都添上

  3. 改app.js

    手动隐藏splash screen,在run里面添上

    .run(['$rootScope', function($rootScope) {        // init        // $rootScope.isLoading = false;        // hide splash immediately        if(navigator && navigator.splashscreen) {            navigator.splashscreen.hide();        }    });}])
    Nach dem Login kopieren

    这样就好了,不要延时调用hide,否则仍然会出现白屏(有些解决方案要求$timeout 50毫秒hide,仍然会出现白屏,不要这样做)

    最怨念的问题结束了,看似简单的功能,想要有 完美的原生体验 却很难,奇奇怪怪的问题很难解决,目前可行的解决方案可能过段时间就不行了,可以查看 White page showing after splash screen before app load 感受一下

    八.安卓版本签名发布

    各种签名方法都过时了,目前(2016/1/9)可以用的签名方法如下:

    1. 在MyApp\platforms\android创建keystore

      具体步骤请查看: Ionic toturial for building a release.apk

    2. 创建release-signing.properties文件

      具体步骤请查看: How to automatically sign your Android apk using Ionic framework and Crosswalk

    3. 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

    看着还不错吧,非卖品,不赠送~

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage