之前做个小移动客户端,图方便快捷,使用了ionic来开发,整体还是挺顺畅的,就是不太习惯yong其中碰到一些小坑,
都是一些知道了就很简单,不知道就很蛋疼的东西,所以做个笔记,帮初次接触ionic和angularjs的人省点事儿
1.ionic中的CORS(跨域)问题
这个问题一般刚接触ionic的都会遇到,在浏览器中通过ionic serve调试的时候,请求api时会报错

XMLHttpRequest cannot load http://localhost:8080/api/p/1. No
'Access-Control-Allow-Origin' header is present on the requested

  1. Origin 'http://localhost:8100' is therefore not allowed
    access.

网上也有不少解决方案,这边只提供一个最简单的
直接安装一个chrome插件,名字就叫:“Allow-Control-Allow-Origin: *”
地址在 https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi
然后直接用插件打开cors就行了
cors.png

2.$resource的结果获取提示未定义(undefined)的问题

如果定义了一个servive:

.service('DemoService',['$q','$resource', 'Constants', function($q,$resource, Constants) {

    var postResource = $resource(Constants.API.baseUrl+'/p/:pid', {pid: '@pid'});

    var post = {
      getPostDetail: function(_pid) {
        return postResource.get({pid:_pid});
      }
    }

    return post;

  }])

然后在controller中调用获取数据并使用

var postDetail = DemoService.getPostDetail($stateParams.pid);

假设返回的是类似于

{"status":"Y","message":"成功","postInfo":{"id":113,...}}

这样的json串,如果我们直接取值

postDetail.status

这样就会报错,提示undefined,从而取不到值,因为$resource的结果是异步返回的,直接调用方法并不能立即就取到返回值。而如果直接$scope.postDetail = postDetail.postInfo的话,页面是可以正常显示的,因为当数据没有返回之前,模板引擎不会渲染,一旦异步数据获取完成,会自动触发模板引擎的渲染机制把数据呈现到视图中。
所以如果我们要在controller中获取返回值的话,只要这么写就行了

DemoService.getPostDetail($stateParams.pid).$promise.then(
function(successData) {
//获取成功后处理
var detail = successData.status;
},
function(failData) {
//获取失败后处理
});

3.ion-refresher和ion-infinite-scroll调用多次的问题

一个页面上,我同时使用了ion-refresher和ion-infinite-scroll用来下拉刷新当前数据以及到底自动获取下一页内容。
偶然发现当ion-refresher下拉刷新之后,页面内容刷出来的一瞬间,infinite的方法被调用了多次,因为页面内容当时还没刷出来,列表一片空白,所以此时页面其实就是已经默认到了最底部了,于是就触发了获取下一页的方法
解决方法也很简单,就是设置一下immediate-check的值

<ion-infinite-scroll ng-if="!noMorePage" immediate-check="false" 
    on-infinite="queryNext()" distance="1%">
</ion-infinite-scroll>

这个设置官方解释是

Whether to check the infinite scroll bounds immediately on load

就是设置是否在页面加载后立刻触发on-infinite的方法,设为false后,则只有滚动到页面边缘时才会触发,即使页面加载出来已经到最底部,不滚动一下的话也是不会触发的
至于$scope.$broadcast('scroll.refreshComplete');$scope.$broadcast('scroll.infiniteScrollComplete');
广播下拉刷新和滚动触发的停止事件就不多说了,官方都有说明

4.list点击跳转后返回,list滚动到了顶部(不知道算不算坑)

list跳转后返回无法保持原位置,而是回到了页面顶部,翻了官方论坛不少帖子,试了不少次,后来把ion-content上的overflow-scroll="true"去掉貌似就行了~

5. $http.post表单提交的问题

ionic的表单提交,用$http.post之后发现后端取不到表单值,google之后找到一个解决方案,直接贴下代码,放到.config里就行

// Use x-www-form-urlencoded Content-Type
  $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';

  /**
   * The workhorse; converts an object to x-www-form-urlencoded serialization.
   * @param {Object} obj
   * @return {String}
   */ 
  var param = function(obj) {
    var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
      
    for(name in obj) {
      value = obj[name];
        
      if(value instanceof Array) {
        for(i=0; i<value.length; ++i) {
          subValue = value[i];
          fullSubName = name + '[' + i + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value instanceof Object) {
        for(subName in value) {
          subValue = value[subName];
          fullSubName = name + '[' + subName + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value !== undefined && value !== null)
        query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
    }
    return query.length ? query.substr(0, query.length - 1) : query;
  };
 
  // Override $http service's default transformRequest
  $httpProvider.defaults.transformRequest = [function(data) {
    return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
  }];

6. 在android上,开机图片(SplashScreen)不显示,只显示了2,3秒空白
这个问题官方论坛上讨论的比较多,各个人解决方案也不一样,有说把config.xml里的SplashScreenDelay设置时间延长的;有说用了Crosswalk之后不兼容的,因为我也没用Crosswalk,我自己不显示开机画面的原因是:“没装splashscreen插件”
解决方案:直接安装插件后重新编译,然后就搞定了

ionic plugin add org.apache.cordova.splashscreen

常用命令:

ionic lib update    更新ionic库

ionic platform add ios        添加ios平台
ionic platform add android    添加android平台

ionic build ios        编译为ios app
ionic build android    编译为android app