初学ionic--自学整理知识点总结(3)

    写这篇博客是总结一下ionic插件的使用,真是坑死我了,垃圾东西毁我青春的大好年华,一些项目中会有各种各样的需求要调用手机底层功能的时候,或是一些比较复杂功能的实现,最先想到的肯定就是查找有没有对应功能的插件在引用插件到项目中去,不需要自己去造*,当然自己也造不出来,毕竟混合开发本事的意义就在于简化开发流程时间和成本(我也不知道究竟是不是这样,但是我觉得是这样子,我觉的如果你接的是个外包项目,不需要对未来的项目负责的话,那用混合开发无疑是最好的选择啊,一个前端angular js很厉害的工程师转学ionic框架简直不要太轻松了,我这种android开发的渣渣,转到前端语言去开发app就觉得好恶心,很多东西都很不方便很麻烦,遇见一点问题之后解决不掉查资料好麻烦,然后大多数的问题还不是代码逻辑的问题,而是插件的引用版本兼容啦,打包到不同平台下各个平台的应用又会出现各种不一样的问题啦,想把这些小问题全部先放下来,但是做到后面的时候,你就会发现,一遇到问题就会想起来是不是之前先放下的小问题引发的这种报错?就好像插件下载中总会显示各种各样的warning提醒,总会好奇为什么或是什么东西引起的这种提醒?但对于刚接触不久的我来说,似乎不是马上清楚明白的知道各种原理why?而好像更多是在最快的时间内去开发不同种类的app,把官网中文档介绍的代码功能全部搞一遍..在把angular4的知识融汇一遍,只需要去知道how to do?就可以了?这样来学习?哎..总之如果不是因为它可以生成不同平台下的项目,我压根就觉得他没有存在的必要)

    下午的时候我在用npm install 下载一些插件,但是都会有报错信息弹出,各种五花八门的版本信息需要升级或者提示没有安装,然后我就在config文件和package文件中徘徊来徘徊去的,各种命令行下载更新插件,后来直接放弃,错误越报越多...于是我在网上找了一个项目引用的这个插件把人家的配置文件直接copy到自己的工程中去,然后删除自己本项目的node_modules引入插件的包,在重新 install 一次项目,问题虽然解决,但是还有很多的warn信息在提示,看的自己头皮发麻,很担心未来会不会埋下什么定时炸弹一样... 然后就正式开始写代码,但是后来写完再浏览器下运行时,发现个一个关于file文件插件的报错信息,我就各种排查错误,打断点,*google,到国外的论坛(我那个英文的阅读理解能力..只能复制到翻译软件里..很麻烦费时间...)但是还是没有解决,我就默默的去了厕所抽了两根烟,安慰自己说刚才的都是一场梦,没关系的梦会醒的 没关系没关系... ... 到了后来我把工程相关页面配置文件,页面等全部相关文件保存了一遍,终于成功的运行啦~!? 但是一刷新又出错了! 我无奈重启serve又恢复了运行...又没错误了... 没错了... 对的这就是ionic 一个让你有时候想打死他但是还打不着的东西 气死本帅宝宝了!


1.我安装的插件是照相机功能的相关插件,功能是修改头像,通过摄像头照或是本地图片库去取,然后上传到后台的功能,首先创建一个测试按钮,意为点击后跳转到一个选择上传图片的功能页面:

<ion-content>
<div padding>
<button ion-button color="primary" block (click)="gotoHeadface()">修 改</button>
</div>
</ion-content>


2.然后在这个布局的前台ts文件中去写点击事件的跳转:

gotoHeadface() {
this.navCtrl.push(HeadfacePage);
}


3.跳转到修改头像页面后,进行头像的选择以及上传的操作,html页面写成这样:

<ion-header>
<ion-navbar>
<ion-title>设置头像</ion-title>
</ion-navbar>
</ion-header>


<ion-content padding>
<img src="{{pathForImage(lastImage)}}" style="width:100%;height:60%;" [hidden]="lastImage === null">
<h3 [hidden]="lastImage !== null">请从图片库中选择一个图片。</h3>
</ion-content>

<ion-footer>
<ion-toolbar color="primary">
<ion-buttons>
<button ion-button icon-left (click)="presentActionSheet()">
<ion-icon name="camera"></ion-icon>选择...
</button>
<button ion-button icon-left (click)="uploadImage()" [disabled]="lastImage === null">
<ion-icon name="cloud-upload"></ion-icon>上传
</button>
</ion-buttons>
</ion-toolbar>
</ion-footer>

[hidden]隐藏图片缩略图,当前台的img没有信息时不显示,当通过照相或是图片库选择后给lastImage赋值后,返回页面会显示出选择/照的图片显示出来,[disable]中也是同样,当没有图片被选择的时候,显示上传的按钮图标是不可点击的灰色状态.


4.修改头像页面的ts代码:

import { Component } from '@angular/core';
import { IonicPage, normalizeURL, NavController, NavParams, ViewController, ToastController, ModalController, LoadingController, ActionSheetController, Platform } from 'ionic-angular';
import { BaseUI } from '../../common/baseui';
import { RestProvider } from '../../providers/rest/rest';

//导入四个外部加载进来的组件
import { File } from '@ionic-native/file';
import { Transfer, TransferObject } from '@ionic-native/transfer';
import { FilePath } from '@ionic-native/file-path';
import { Camera } from '@ionic-native/camera';

declare var cordova: any; //导入第三方的库定义到 TS 项目中

@IonicPage()
@Component({
selector: 'page-headface',
templateUrl: 'headface.html',
})
export class HeadfacePage extends BaseUI {

userId: string;
errorMessage: string;
lastImage: string = null;

constructor(public navCtrl: NavController,
public navParams: NavParams,
public modalCtrl: ModalController,
public loadingCtrl: LoadingController,
public rest: RestProvider,
public actionSheetCtrl: ActionSheetController,
public camera: Camera,
public transfer: Transfer,
public file: File,
public filePath: FilePath,
public platform: Platform,
public toastCtrl: ToastController,
public viewCtrl: ViewController
) {
super();
}

ionViewDidEnter() {
// 这里是上传后台的图片信息 接口中需要有userId值 因为是Demo的形式
// 所以就没有把注册/登录 获取userId的获取或是存储的代码写在这个里面
// 就直接用一个测试的userId进行写死
this.userId = "5ab49056647eb42c8c196305";
}

/**
* 点击选择时 前台的执行代码
* actionSheet弹出窗口
*
* @memberof HeadfacePage
*/
presentActionSheet() {
let actionSheet = this.actionSheetCtrl.create({
title: '选择图片',
buttons: [
{
text: '从图片库中选择',
handler: () => {
this.takePicture(this.camera.PictureSourceType.PHOTOLIBRARY);
}
},
{
text: '使用相机',
handler: () => {
this.takePicture(this.camera.PictureSourceType.CAMERA);
}
},
{
text: '取消',
role: 'cancel'
}
]
});
actionSheet.present();
}

/**
* 执行camera插件功能代码
* 官网的api有详细的说明
* 这里就不多描述插件属性的东西
*
* @param {any} sourceType
* @memberof HeadfacePage
*/
takePicture(sourceType) {
//定义相机的一些参数
var options = {
quality: 100, //图片的质量
sourceType: sourceType,// 表示用何种type
saveToPhotoAlbum: false, //是否保存拍摄的照片到相册中去
correctOrientation: true //是否纠正拍摄的照片的方向
};

//获取图片的方法
this.camera.getPicture(options).then((imagePath) => {
//特别处理 android 平台的文件路径问题
if (this.platform.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
this.filePath.resolveNativePath(imagePath) //获取 android 平台下的真实路径
.then(filePath => {
//获取正确的路径
let correctPath = filePath.substr(0, filePath.lastIndexOf('/') + 1);
//获取正确的文件名
let currentName = imagePath.substring(imagePath.lastIndexOf('/') + 1, imagePath.lastIndexOf('?'));
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
});
}
else {
//获取正确的路径
var correctPath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
//获取正确的文件名
var currentName = imagePath.substr(imagePath.lastIndexOf('/') + 1);
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
}
}, (err) => {
super.showToast(this.toastCtrl, "选择图片出现错误,请在 App 中操作或检查相关权限。");
});
}

//将获取到的图片或者相机拍摄到的图片进行一下另存为,用于后期的图片上传使用
copyFileToLocalDir(namePath, currentName, newFileName) {
this.file.copyFile(namePath, currentName, cordova.file.dataDirectory, newFileName).then(success => {
this.lastImage = newFileName;
}, error => {
super.showToast(this.toastCtrl, "存储图片到本地图库出现错误。");
});
}

//为文件生成一个新的文件名
createFileName() {
var d = new Date(),
n = d.getTime(),
newFileName = n + ".jpg"; //拼接文件名
return newFileName;
}

//处理图片的路径为可以上传的路径
public pathForImage(img) {
if (img === null) {
return '';
} else {
return normalizeURL(cordova.file.dataDirectory + img);
}
}

/**
* 上传图片到后台的执行代码
*
* @memberof HeadfacePage
*/
uploadImage() {
var url = 'https://imoocqa.gugujiankong.com/api/account/uploadheadface';
var targetPath = this.pathForImage(this.lastImage);
var filename = this.userId + ".jpg"; //定义上传后的文件名

//fileTransfer 上传的参数
var options = {
fileKey: "file",
fileName: filename,
chunkedMode: false,
mimeType: "multipart/form-data",
params: { 'fileName': filename, 'userid': this.userId }
};

const fileTransfer: TransferObject = this.transfer.create();

var loading = super.showLoading(this.loadingCtrl, "上传中...");

//开始正式地上传
fileTransfer.upload(targetPath, url, options).then(data => {
loading.dismiss();
super.showToast(this.toastCtrl, "图片上传成功。");
//在用户看清弹窗提示后进行页面的关闭
setTimeout(() => {
this.viewCtrl.dismiss();
}, 3000);
}, err => {
loading.dismiss();
super.showToast(this.toastCtrl, "图片上传发生错误,请重试。");
});
}
}

需要注意的是调用相机手机图库和图片的上传需要导入相关的一系列插件,你需要的是较好的网络状态,没配置国内源地址的要装好*的v*n并保证网速良好,下载的插件在下面会写:

npm install --save @ionic-native/[email protected]  @ionic-native/[email protected]  @ionic-native/[email protected]  @ionic-native/[email protected] 

ionic cordova plugin add [email protected]  --save

ionic cordova plugin add [email protected]  --save

ionic cordova plugin add [email protected]  --save

ionic cordova plugin add [email protected]  --save

(值得注意的是本地文件夹权限有时候没有获取到对应权限,需要执行sudo chmod -R 777 项目文件路径,再就是安装中会出现各种各样的warning提醒,之前我很较真,想解决提示的内容,后来发现以我初学的水平好像是无法解决的,所以不要在意,只需要看你控制台的信息有没有出现error就可以了)


5.还有一点不要忘记的是每次添加页面也好,导入插件也好,不要忘记在 app.module.ts文件内添加导入:

import { File } from '@ionic-native/file';// 新增
import { Transfer, TransferObject } from '@ionic-native/transfer';// 新增
import { FilePath } from '@ionic-native/file-path';// 新增
import { Camera } from '@ionic-native/camera';// 新增


providers: [
StatusBar,
SplashScreen,
{ provide: ErrorHandler, useClass: IonicErrorHandler },
RestProvider,
File,// 新增
Transfer,// 新增
FilePath,// 新增
Camera,// 新增
QRScanner,
AppVersion
]


6.之后就可以进行测试了,在网页中能打开设置头像的页面就可以了,就可以生成不同平台下的项目在真机中测试了,因为网页端无法测试手机的真实功能只能显示一些页面,一些是部分截图:

初学ionic--自学整理知识点总结(3)

初学ionic--自学整理知识点总结(3)

初学ionic--自学整理知识点总结(3)

(上传到后台成功后会显示toast信息,在把当前的页面dismiss掉,那个只有一个按钮的页面,可以是你项目中的个人资料简介显示的页面,每个个人主页都会有对头像和个人信息进行更改的地方,当上传头像后返回到当前的页面头像就要进行刷新操作,因为我比较懒这里就直接写的一个按钮,没有原头像的信息和返回后原头像自动刷新更改的那一个过程,但是下面也简单的介绍一下页面dissmiss掉后原页如何刷新) 

    其实很简单啊就在生命周期中进行头像的http请求就好了,每次进入到该页面都会再次请求,虽然这种方式网络请求过于频繁,但是对于app的优化问题一直以来都是一门很大的学问,一个app很容易做出来,但是好的app却很难设计到完美的地步,只有一个接近于最好的状态.

ionViewDidEnter() {
this.loadUserPage();
}

7.对于插件的使用重点还是 ionic官网的理解了,在好的博客写的肯定也没有官网介绍的全面,只能就单独的某个点来说能更加的详细易于理解一点,但是整体官网的介绍还是很全面很完美的,下面介绍的是一个比较简单的插件,因为原生的app获取本手机的一些配置信息属性版本较为容易,一直没有把思维从原生开发转到混合开发,所以炸得一看这个插件是获取版本信息的,有何必要?后来才缓过劲来,原来混合开发的代价也不是没有的,比如说像上面照片的路径问题,插件代码没有完美的兼容,你需要统一不同的操作平台下的照片存储路径,你需要解决不同平台下的兼容问题,图片的风格显示问题等等,还有各个插件的兼容升级问题也很头疼.下面来看这个插件的官网的基本介绍:

初学ionic--自学整理知识点总结(3)

首先官网会对插件进行一个简单的介绍,然后会对项目的插件下载进行讲解,如上就是一个cordova一个npm包的下载


8.然后官网的重点当然是 How to Using了:

初学ionic--自学整理知识点总结(3)

9.然后自己的项目里面就是根绝以上的介绍自己编写,获取到信息之后绑定到html页面中就可以了.

<ion-content>
<ion-list>
<ion-item>
AppName: {{appName}}
</ion-item>
<ion-item>
PackageName: {{packageName}}
</ion-item>
<ion-item>
VersionCode: {{versionCode}}
</ion-item>
<ion-item>
VersionNumber: {{versionNumber}}
</ion-item>
</ion-list>
</ion-content>


然后ts页面代码:

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { AppVersion } from '@ionic-native/app-version';

/**
* Generated class for the VersionsPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/

@IonicPage()
@Component({
selector: 'page-versions',
templateUrl: 'versions.html',
})
export class VersionsPage {

appName: string;
packageName: string;
versionCode: string;
versionNumber: string;

constructor(public navCtrl: NavController,
public navParams: NavParams,
public appVersion: AppVersion) {
}

ionViewDidLoad() {
this.appVersion.getAppName().then(v => {
this.appName = v;
});
this.appVersion.getPackageName().then(v => {
this.packageName = v;
});
this.appVersion.getVersionCode().then(v => {
this.versionCode = v;
});
this.appVersion.getVersionNumber().then(v => {
this.versionNumber = v;
});
}

}


显示效果就是:

初学ionic--自学整理知识点总结(3)


    以上就是对ionic插件的下载到使用的总结,一共两个分别是关于camera一个关于version的简单总结介绍,再就是之前我写过一个关于扫码的插件功能,使用测试时感觉是没问题的,但是刚才在真机测试的时候发现在真机中调试页面白屏,我在css中设置的透明属性没有执行,然后扫码的功能也没有启动,我还在找原因中,找到原因后会在下面总结使用以及注意事项,下面我会着重把ionic的官网给看一遍,在将angular4的基础教程过一下,有时间的话在将css的东西自学整理一下,之前本以为css只是一些html的布局属性,但是没想到还可以完成动画效果,然后很好奇想从同学习一下.以上谢谢大家么么哒~