惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
H
Heimdal Security Blog
K
Kaspersky official blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
Schneier on Security
G
GRAHAM CLULEY
U
Unit 42
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
CERT Recently Published Vulnerability Notes
Google DeepMind News
Google DeepMind News
罗磊的独立博客
Stack Overflow Blog
Stack Overflow Blog
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
C
Cisco Blogs
Cyberwarzone
Cyberwarzone
T
The Exploit Database - CXSecurity.com
Project Zero
Project Zero
Security Archives - TechRepublic
Security Archives - TechRepublic
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
V
Visual Studio Blog
博客园 - Franky
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
Jina AI
Jina AI
P
Proofpoint News Feed
P
Proofpoint News Feed
有赞技术团队
有赞技术团队
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 聂微东
T
The Blog of Author Tim Ferriss
Spread Privacy
Spread Privacy
Application and Cybersecurity Blog
Application and Cybersecurity Blog
IT之家
IT之家
S
Security Affairs
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
N
News | PayPal Newsroom
Cloudbric
Cloudbric
AWS News Blog
AWS News Blog
W
WeLiveSecurity
The Last Watchdog
The Last Watchdog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
NISL@THU
NISL@THU

Giscafer's blog

博客停更说明 使用 ViewContainerRef 探索Angular DOM操作 GIS520论坛关闭停止运营 ionic3之图片选择插件com.synconset.imagepicker ionic3开发遇到的一些问题及解决方法 ionic3之自定义tabs菜单图标 ionic3 之Android的actionsheet渲染和ios一致 Hexo博客畅言评论插件试用 从GISer到互联网前端工程师,JUST DO IT angular实现IM聊天图片发送 Cafe主题v1.0发布 React搭建百度前端技术学院习题演示SPA react-ponitor React 与 Redux 实践 —— 城市筛选面板 1.Two Sum 如何组件化开发WebGIS系统 2016年末总结 代码理解React组件生命周期过程 hexo-theme-cafe
ionic3之组件封装篇
2017-07-05 · via Giscafer's blog

ionic3官方提供了较多好用的组件和API。但是有些时候,我们用到的交互方式,官方的组件不是全都满足的。比如类似网易新闻APP,菜单的滑动效果。或者一些和业务接口紧密联系的组件。

滑动菜单效果实现

推荐使用插件ionic2-super-tabs,功能强大。下边是slides + slides组合挖坑尝试

最终效果如下:

slides+slides实现菜单滑动

简单的代码如下:(完善的话实际上需要填掉很多坑,这也可能是为什么官方没有提供这类的组件吧)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<ion-header>

<ion-navbar>

<ion-title>slide-tab-demo</ion-title>

</ion-navbar>

<div>

<task-slide (slideClick)="slideClick($event)" [slides]="tabs" [selectedIndex]="navSelectedIndex" [taskType]="segment" [pageNumber]="4"></task-slide>

</div>

</ion-header>

<div style="height: 100%;;background-color:#999">

<ion-slides #slidesRef (ionSlideDidChange)="slideChanged($event)">

<ion-slide *ngFor="let slide of slides; let i = index;">

<div class="list has-header" id="{{i}}">

<ion-label>{{slide.name}}</ion-label>

</div>

</ion-slide>

</ion-slides>

</div>

ts代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

import { Component, ViewChild } from '@angular/core';

import { IonicPage, NavController, NavParams, Slides, Tabs } from 'ionic-angular';

@Component({

selector: 'page-slide-tab-demo',

templateUrl: 'slide-tab-demo.html',

})

export class SlideTabDemoPage {

@ViewChild("slidesRef")

slidesRef: Slides;

@ViewChild("tabsRef")

tabsRef: Tabs;

slides: any[] = [];

currentTabId = "tab1";

tabs: any[] = [];

navSelectedIndex = 0;

constructor(

public navCtrl: NavController,

public alert: Alert,

public navParams: NavParams

) {

this.slides = [{

name: '头条新闻'

}, {

name: '娱乐新闻'

},

{

name: '体育新闻'

}];

this.tabs = [{

_name: "头条",

num: 99

}, {

_name: "娱乐",

num: 0

}, {

_name: "热点",

num: 0

}, {

_name: "体育",

num: 4

}, {

_name: "财经",

num: 0

}, {

_name: "汽车",

num: 0

}, {

_name: "时尚",

num: 0

}];

}

slideClick(slideIndex) {

this.slidesRef.slideTo(slideIndex);

}

slideChanged($event) {

let currentIndex = this.slidesRef.getActiveIndex();

this.navSelectedIndex = currentIndex;

}

}

抽屉效果

先看效果:

ionic3-custom-component2.gif

抽屉效果,在做一些筛选选择条件的时候,交互首选的。这个官方没有提供组件实现,实现这个功能也必将简单,加上使用ng4的话,动画效果也很容易切换。下边是代码。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<ion-content>

<ion-backdrop *ngIf="toggleState==='in'" style="opacity:0.4"></ion-backdrop>

<div class="panel" [@toggleState]="toggleState">

<div margin-top>

<button ion-button small outline (click)="togglePanel()"> 按钮1 </button>

<button ion-button small outline (click)="togglePanel()"> 按钮2 </button>

<button ion-button small outline (click)="togglePanel()"> 按钮3 </button>

</div>

</div>

<div margin-top>

<span>{{testData}}</span>

<span>{{testText}}</span>

</div>

<div style="margin-top:240px;">

<button ion-button small (click)="togglePanel()"> 这里是其他东西 </button>

</div>

</ion-content>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

* 抽屉动画+loading api调用举例

*/

@Component({

selector: 'page-api-test',

templateUrl: 'api-test.html',

animations: [

trigger('toggleState', [

state('in', style({

top: '45px'

})),

state('out', style({

top: '-200px'

})),

transition('out => in', animate('300ms ease-in')),

transition('in => out', animate('800ms ease-out'))

])

]

})

export class ApiTestPage {

toggleState = 'out';

toggle: boolean = true;

constructor( ) {

}

togglePanel() {

this.toggle = !this.toggle;

this.toggleState = this.toggle ? 'out' : 'in';

}

}

重要的是要添加ion-backdrop组件,作为掩膜,禁止content内容可以点击。

图片下载

需要插件支持

  • npm install @ionic-native/transfer

  • ionic cordova plugin add cordova-plugin-file-transfer

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

* 下载文件

* @param url

* @param fileName

*/

download(url, fileName) {

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

return fileTransfer.download(url, this.file.dataDirectory + 'download_' + fileName);

}

downloadImage() {

let url = 'https://img.alicdn.com/tps/TB1WvtYSXXXXXX4XXXXwu0bFXXX.png';

let fineName = 'tmail_' + new Date().getTime() + '.png';

this.download(url, fineName).then((entry) => {

console.log('下载后路径:'+entry.toURL())

}, (error) => {

});

}

本地图片读取上传

本地图片路径有两种格式,如下方代码注释,通过file插件中的readAsDataURL方法,将图片读取为Base64的格式,如果是后端接口是支持base64上传图片就可以直接上传,不然就如下使用dataURItoBlob方法转成Blob上传。

下边方法都封装在nativeService.ts服务类里

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

* Base64转File对象

* @param dataURI

*/

dataURItoBlob(dataURI) {

var byteString = atob(dataURI.split(',')[1]);

var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

var ab = new ArrayBuffer(byteString.length);

var ia = new Uint8Array(ab);

for (var i = 0; i < byteString.length; i++) {

ia[i] = byteString.charCodeAt(i);

}

return new Blob([ab], { type: mimeString });

}

* 根据原生图片路径获取图片dataUrl

* 支持两种格式路径

* "/data/data/yzt.jzt/files/download_tmail_1499051584861.png"

* /storage/emulated/0/Pictures/IMG_20170626_104451.jpg

*/

readAsDataURLByPath(path: string, callback: Function) {

let that = this;

function fail(err) {

console.log('Cannot found requested file' + err);

}

function gotFile(dataURL) {

let blob = that.dataURItoBlob(dataURL);

callback(blob);

}

let time = new Date().getTime();

if (path) {

if (path.indexOf('file://') !== 0) {

path = 'file://' + path;

}

let fileNames = path.split('/');

let name = fileNames[fileNames.length - 1];

let num = path.lastIndexOf('/');

let dirPath = path.substring(0, num);

this.file.readAsDataURL(dirPath, name).then(fileEnter => gotFile(fileEnter)).catch(err => fail(err));

}

}

上传服务器

将xhr FormData请求方式封装成Promise方法,方便调用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

* 通过android和ios文件路径上传服务器

* Creates a new file in the specific path.

* @param paths 文件路径数组

* ["/storage/emulated/0/Pictures/IMG_20170626_104451.jpg"]

*/

uploadByFileSystem(paths): any {

let fileBlobs = [];

return new Promise((resolve, reject) => {

this.nativeService.showLoading('图片上传中……');

let formData = new FormData();

for (let path of paths) {

this.nativeService.readAsDataURLByPath(path, blob => {

fileBlobs.push(blob);

formData.append('file', blob, blob.name || 'jzt_tmall_' + fileBlobs.length + '.jpg');

if (fileBlobs.length === paths.length) {

this.settings.getValue('jwt').then(jwt => {

let xhr = new XMLHttpRequest();

xhr.onreadystatechange = () => {

if (xhr.readyState == 4) {

this.nativeService.hideLoading();

if (xhr.status >= 200 && xhr.status < 300) {

resolve({ xhr: xhr, formData: formData });

} else {

reject({ xhr: xhr, formData: formData });

}

}

};

xhr.open('POST', UPLOAD_URL, true);

xhr.setRequestHeader("Authorization", "Bearer " + jwt);

xhr.send(formData);

});

}

});

}

});

}

相册选择图片上传

使用插件 Telerik-Verified-Plugins ImagePicker即可选择图片,得到Base64格式或者url,上传代码和上边类似。

参考文章

http://ourcodeworld.com/articles/read/22/solve-native-path-of-android-content-if-resolvelocalfilesystemurl-doesn-t-work

微信公众号

giscafer

未完待续……

推荐文章