Ionic 开发中遇到的常见问题及解决方案

简介: Ionic 常见问题及解决方案
+关注继续查看

前言
Ionic是目前较为流行的Hybird App解决方案,在Ionic开发过程中会遇到很多常见的开发问题,本文尝试对这些问题给出解决方案。

一些常识与技巧
list 有延迟,可以在ion-content处使用 overflow-scroll="true"尝试
在上用ng-click上是没效果的
标签内的事件会在整个label内被触发,点哪都触发
快捷修改背景色style="background-color: #212326;"
能用ng-if就用ng-if,ng-if的效率比ng-show和ng-hide高
直接在ion-list中的ion-item中并不能触发ng-click事件,可以在item中的元素上再套一层div
可以用ng-class="{'important': post.important}"配合css 根据列表元素显示不同的效果
获取日期用$filter,var postdate = $filter('date')(date, 'yyyy-MM-dd HH:mm:ss');
列表中的元素不能写成 id : 4,应写成 id : "4",注意在创建id变量的时候也需要转成string,如var id = InfoListService.getListLength()+1+"";
使用$log进行log输出,为什么用$log而不是console.log呢?可以看看这个
在安卓上的体验比较差,动画有延迟?可以试试ionic集成的crosswalk
controllers和services 的文件名可能会重合,但是他们意义差不多,可以将controllers中的文件名小写,对应的services中的文件名大写进行区分,或者加后缀xxxControler,xxxService
安装cordova插件的时候用ionic plugin add ...的方式添加,这样会在package.json中添加这个插件的条目,如果有人clone了你的项目想在本地运行,可以用ionic state restore它会根据cordovaPlugins条目安装对应的插件。如果直接用cordova plugin add 安装则不会更新package.json。

上传base64编码的时候如果提示413错误,是因为文件过大导致的,可以在nodejs中设置bodyparser的文件限制:

var bodyParser = require('body-parser');
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));


img 中 base64编码的图片无法显示?在源码中发现angular添加了unsafe标签?需要在白名单中添加data:image

$compileProvider.imgSrcSanitizationWhitelist(/^s*(https?|ftp|mailto|content|file|assets-library):|data:image//);


有时候pm2运行有问题,重启一下即可

在ios设备上运行ionic run ios --device

问题列表
1.如何在某个界面中去掉导航栏?
2.如何在ionic中加载本地图片?
3.如何在ionic中嵌入网页代码?
4.如何将template加载到某个tab或某个sidemenu项目下?
5.运行serve命令时ionic报错?
6.用docker跑ionic的时候,不能把地址绑定到0.0.0.0怎么处理?
7.加载页面的时候会看到双括号一闪而过?
8.更新了数据,如何让界面更新呢?
9.如何实现IonicView中card上面有一列分割线的效果?
10.controller.js和service.js文件越来越大怎么办?
11.如何寻找优秀的范例代码?
12.如何显示相对时间?
13.发布应用的时候如果遇到翻译错误即MissingTranslation怎么办?
14.如何在列表右下方添加时间等信息?
15.如何回到上一页面?
16.如何关闭应用?
17.在安卓设备上如何让title居中?
18.如何让在sidemenu中的headerbar能够显示头像等其他信息?
19.ionic的subheader挡住了内容区域怎么办?
20.对于需要添加数据的list,在添加数据后页面不能及时刷新造成卡顿怎么办?
21.ionic如何处理回退按钮?例如询问用户是否真的要退出应用
22.ionic如何实现对每个请求都添加认证信息或认证失败自动重新登录?
23.ionic如何实现搜索框内的全部清除按钮?
如何在某个界面中去掉导航栏?
如果某个界面上不想要导航栏,可以简单地在最顶端的标签中添加hide-nav-bar="true"

如何在ionic中加载本地图片?
对于css文件夹中的样式文件中如果要调用本地的图片的话,从该css文件所在的文件夹开始算,例如www/css/style.css要加../,否则在浏览器中可以正常显示,在设备上不行,结构如下所示:
.login-page {
background:url(../img/signup_bg.png);
background-size: cover;
background-repeat: no-repeat;
}
但是对于在页面中定义的图片路径,从www路径开始算,否则浏览器中可显示,但设备上不行,img文件夹和index.html在一级,如:
commander.jpg

如何在ionic中嵌入网页代码?
使用ng-bind-html这个类,不过它会过滤原始html的标签,我们可以引入$sce模块,用$sce.trustAsHtml()方法信任我们获取的网页

如何将template加载到某个tab或某个sidemenu项目下?
 可以指定name,然后在子状态中使用该name,ionic就知道该把该状态的template渲染到哪边了。例如:
// signup page
.state('auth.signup', {
url: '/signup',
views: {

   'auth-signup': {
       templateUrl: 'templates/auth-signup.html',
       controller: 'SignUpCtrl'
   }

}
})

另有一个tabs中声明该auth-signup:
icon-off="ion-ios-personadd-outline" href="#/auth/signup">

运行serve命令时ionic报错?
ionic $ An uncaught exception occured and has been reported to Ionic
看看你是不还有一个终端在运行着serve呢?

用docker跑ionic的时候,不能把地址绑定到0.0.0.0怎么处理?
可以用ionic serve -all的方法解决

加载页面的时候会看到双括号一闪而过?
angularjs 在使用双括号的时候,第一个加载的页面,也就是应用中的index.html,其未被渲染好的模版可能会被用户看到。用ng-bind就不会遇到这个问题。造成这种现象的原因是,浏览器需要首先加载HTML页面,渲染它,然后Angular才有机会把它解释成你期望看到的内容。不过好消息是,在大多数的模版中你依然可以使用双括号.但是对于index.html页面中的数据绑定操作,建议使用ng-bind。
ng-bind使用方式如下: 

更新了数据,如何让界面更新呢?
可以用广播,注意$broadcast 和 $emit的区别

如何实现IonicView中card上面有一列分割线的效果?
在css里定义

info-up {

border-top: 4px solid #f06336;
}

controller.js和service.js文件越来越大怎么办?
所有的控制器不必都放在controllers.js这一个文件中,可以新建controllers文件夹,
然后把每个controller都建一个.js文件,同理services和utils等都是.但注意要在index.html中head部分声明.但是为了避免他们相互覆盖,第一个加载的js中模块中要加[…],其他都不需要。如:
// File : /js/directives/mainDirective.js
angular.module('app.directives',[]);

// File : /js/directives/myGreatDirective.js
angular.module('app.directives')

.directive('myGreatDirective', function(){
    return {
        //...
    }
});

// File : /js/directives/myBetterDirective.js
angular.module('app.directives')

.directive('myBetterDirective', function(){
    return {
        //...
    }
});

...
看angularjs-code-organization了解更多,嗯这篇文章写的还不是best practice,因为你还得记着自己把[]写到那个模块里了,统一地写在app.js中即可,在app.js最下面加上类似:
angular.module('fcws.controllers',['ionic', 'fcws.services']);
angular.module('fcws.services', []);
可以达到和上面一样的效果,而且可以统一管理.

如何寻找优秀的范例代码?
目前有些ionic 的app没有进行代码混淆,至少ionic官方的ionic view没有进行代码混淆,下载他们的app,文件名改成zip,解压,所有的 www文件都在assets文件夹中,相当于开源了有木有,看看那些最优秀的practice。看中哪些优秀的app,下下来,如何在googleplay上下载?把googleplay应用的地址贴到apps.evozi中。

如何显示相对时间?
如几分钟前,几天前等,可以用momentjs,看这篇教程

发布应用的时候如果遇到翻译错误即MissingTranslation怎么办?
暂时的解决方法是,不进行翻译校正, 在 /platforms/android/build.gradle 中的android {}节中加入:
lintOptions {

                     disable 'MissingTranslation'
                        disable 'ExtraTranslation'

}

如何在列表右下方添加时间等信息?
span 可以用来将时间之类的附加信息显示到列表右边,如下面会将创建时间显示在name的右边:

<img src="../../img/commander.jpg">
<span class="item-note">{{message.create_at}}</span>
<h2 >{{message.name}}</h2>
<p >  {{message.content}}</p>

如何回到上一页面?
用$ionicHistory这个模块,引入该模块后使用goBack([backCount]),backCount指定回去多少个页面(-1代表回去一个页面),默认为-1

如何关闭应用?
ionic.Platform.exitApp();

在安卓设备上如何让title居中?
在headerbar中添加align-title="center",如:

 <h1 class="title">{{username}}</h1>


不过这个设置对ion-view无效,亲测,如果要统一让所有navbar上的title居中(包括上面的headerbar),可以在config里设置,如:
.config(function($stateProvider, $urlRouterProvider,$ionicConfigProvider) {
$ionicConfigProvider.navBar.alignTitle('center');
...
如果要让某一个view title居中,可以用$ionicNavBarDelegate,参考ionic官方文档

如何让在sidemenu中的headerbar能够显示头像等其他信息?
解决方案是去掉headerbar,添加一个avatar到sidemenu content中,如:

<ion-content class="bar-positive">
    <ion-list>
        <ion-item class="item item-avatar item-positive" href="#">
            <img src="img/commander.jpg">
            <h2 class=" light">
                <i class="icon ion-ios-star"></i>{{title}}
            </h2>
            <a>{{username}}</a>
        </ion-item>

ionic的subheader挡住了内容区域怎么办?
解决方案是给加类has-subheader,同理也可以加has-header。如下:

对于需要添加数据的list,在添加数据后页面不能及时刷新造成卡顿怎么办?
可以使用$ionicScrollDelegate.resize();在添加数据后手动进行重新刷新,记得添加依赖

ionic如何处理回退按钮?例如询问用户是否真的要退出应用
可以在app.js的.run方法中增加对硬件回退按钮的注册处理,这里我在大部分页面都想注册该事件,除去有二级历史页面的我单独判断了下,注意增加依赖。
$ionicPlatform.registerBackButtonAction(function(e) {

var current_state_name = $state.current.name;
if(current_state_name !== 'sidemenu.post'
 && current_state_name !== 'sidemenu.contact_town' &&
current_state_name !== 'sidemenu.contact_people'){
    $ionicPopup.confirm({
        title: '退出应用',
        template: '您确定要退出xxxx吗?'
    }).then(function (res) {
        if (res) {
            //ionic.Platform.exitApp();
            navigator.app.exitApp();
        } else {
            console.log('You are not sure');
        }
    });
    e.preventDefault();
    return false;
}else{
    navigator.app.backHistory();
}

},100);

ionic如何实现对每个请求都添加认证信息或认证失败自动重新登录?
在应用的注册或者登录部分,不记名token响应了这个请求并且这个token被存储到本地存储中。当你向后端请求一个服务时,你需要把这个token放在头部中。你可以在app.js的.config方法中使用AngularJS的拦截器实现这个。每次请求都会被拦截并且会把认证头部和值放到头部中,同理如果服务器端响应401或403,跳转到重新登录页面.
$httpProvider.interceptors.push(function ($q, $location, User, $rootScope) {

return {
    'request': function (config) {
        config.headers = config.headers || {};
        if (User.getToken()) {
            config.headers.Authorization = 'Bearer ' + User.getToken();
        }
        return config;
    },
    'responseError': function (response) {
        if (response.status === 401 || response.status === 403) {
            //如果之前登陆过
            if (User.getToken()) {
                $rootScope.$broadcast('unAuthenticed');
            }
        }
        return $q.reject(response);
    }
};

});

ionic如何实现搜索框内的全部清除按钮?
在label中的input不能嵌入按钮,因为ionic对于label中的tap事件会进行重定向到input上。解决方案是将label替换成span或div。如下面的搜索框,注意ng-model需要是一个对象才能置空,变量不行:

 <i class="icon ion-ios-search placeholder-icon"></i>
 <input type="search" placeholder="请输入姓名前缀" ng-model="search.key">
     <i class="icon ion-close-circled placeholder-icon" style="vertical-align: middle;"
        on-tap="clearSearch()" ng-if="search.key.length"></i>


中添加这个插件的条目,如果有人clone了你的项目想在本地运行,可以用ionic state restore它会根据cordovaPlugins条目安装对应的插件。如果直接用cordova plugin add 安装则不会更新package.json。

上传base64编码的时候如果提示413错误,是因为文件过大导致的,可以在nodejs中设置bodyparser的文件限制:

var bodyParser = require('body-parser');
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));


img 中 base64编码的图片无法显示?在源码中发现angular添加了unsafe标签?需要在白名单中添加data:image

$compileProvider.imgSrcSanitizationWhitelist(/^s*(https?|ftp|mailto|content|file|assets-library):|data:image//);


有时候pm2运行有问题,重启一下即可

在ios设备上运行ionic run ios --device

目录
相关文章
|
4月前
|
Web App开发 编解码 前端开发
移动端开发一些常见问题的解决方案
移动端开发一些常见问题的解决方案
163 0
移动端开发一些常见问题的解决方案
|
存储 前端开发 API
低代码开发的前后端联调——APICloud Studio 3 API管理工具结合数据云3.0使用教程
最近国内低代码平台APICloud 推出了拖拽式开发模式,通过拖拉组件,设置组件样式、属性、事件,可生成代码。我也是第一时间体验了一下,上一篇分享了一些学习经验。而且还发现新增了一个API管理工具,这篇文章即是分享API管理工具的学习体验。
237 0
低代码开发的前后端联调——APICloud Studio 3 API管理工具结合数据云3.0使用教程
|
API iOS开发 MacOS
关于electron升级调研的心得笔记
关于electron升级调研的心得笔记
292 0
关于electron升级调研的心得笔记
|
存储 监控 前端开发
APM开源方案-SigNoz初体验
最近在调研APM相关的开源方案,发现ATA上这类的文章比较少,准备搞一系列APM的“初体验”文章,那么先从最近github势头较热的SigNoz开始SigNoz简介SigNoz是一套开源APM方案,用于监控应用指标和链路,可以看到调用情况、异常、trace上下链路,也可以自己定义Dashboard。官方对于SigNoz介绍很全面了,不赘述啦。值得注意的是,SigNoz支持OpenTelemetry
4956 2
APM开源方案-SigNoz初体验
|
SQL JSON NoSQL
开源工作流引擎Workflow Core的研究和使用教程
开源工作流引擎Workflow Core的研究和使用教程
1503 0
开源工作流引擎Workflow Core的研究和使用教程
|
前端开发 Shell
如何使用阿里云云开发平台发布vuecli前端项目
如何使用阿里云云开发平台发布vuecli前端项目
|
Linux 应用服务中间件 编译器
msyscuione:基于msys的一体化CUI开发生产环境,支持qt,llvm,ros集成常见web appstack
CUI又称TUI,作为一个开发者和云主机这种服务性环境的使用者,无论有没有意识到,它都是装机时我们大多数情况下第一要装的。linux往往天然集成语言环境和包管理(语言级或系统桌面级),这使得云主机linux装机量往往占首位。相反在windows下没有这样一套东西,因为windows往往作为终端windows应用往往面向要求图形界面的普通用户。
246 0
msyscuione:基于msys的一体化CUI开发生产环境,支持qt,llvm,ros集成常见web appstack
|
Web App开发 小程序 开发工具
小程序云开发CLI工具辅助开发
介绍小程序云CLI的使用技巧,提效小程序云开发。
1937 0
|
C# 容器
开源工作流引擎 Workflow Core 的研究和使用教程
开源工作流引擎 Workflow Core 的研究和使用教程 [TOC] 一,工作流对象和使用前说明 为了避免歧义,事先约定。 工作流有很多节点组成,一个节点成为步骤点(Step)。 1,IWorkflow / IWorkflowBuilder Workflow Core 中,用于构建工作流的类继承 IWorkflow,代表一条有任务规则的工作流,可以表示工作流任务的开始或者 Do() 方法,或工作流分支获取其它方法。
3541 0
相关产品
云迁移中心
推荐文章
更多