本節(jié)課中股毫,我們將制作自定義管道用來(lái)更友好的展示照片的拍攝日期,我們也將完成應(yīng)用的關(guān)鍵部分之一也就是slideshow困介。雖然他沒(méi)有拍照那么復(fù)雜大审,但是他算是整個(gè)應(yīng)用的靈魂。
創(chuàng)建一個(gè)自定義管道
我們?cè)诒緯幕A(chǔ)部分已經(jīng)涵蓋了管道是什么座哩,這里還是跟你簡(jiǎn)單溫習(xí)一下:管道實(shí)際上允許我們?cè)跀?shù)據(jù)進(jìn)行展示之前對(duì)他進(jìn)行修改徒扶。
我們此處的目標(biāo)是創(chuàng)建一個(gè)標(biāo)簽顯示此照片上幾天之前拍攝的,這樣根穷,“3 天前”姜骡,“10 天前”导坟。目前而言,我們已經(jīng)在照片的數(shù)據(jù)上存儲(chǔ)了拍攝日期圈澈,不幸的是惫周,他看起是醬紫的:
Sun Mar 06 2016 00:40:02 GMT+1000 (AEST)
也就是天底下最不友好的日期顯示方式。所以康栈,這里是@Pipe最好的使用情景:我們創(chuàng)建一個(gè)管道用來(lái)接收丑陋的日期格式递递,轉(zhuǎn)換到“X 天前”這樣的格式,然后返回之啥么。
我們先看看如何創(chuàng)建這個(gè)管道漾狼,然后在慢慢討論。
> 修改 src/pipes/days-agp.ts 為如下:
import { Injectable, Pipe } from '@angular/core';
@Pipe({
name: 'daysAgo'
})
@Injectable()
export class DaysAgo {
transform(value, args?) {
let now = new Date();
let oneDay = 24 * 60 * 60 * 1000;
let diffDays = Math.round(Math.abs((value.getTime() - now.getTime())/(oneDay)));
return diffDays;
}
}
@Pipe裝飾器里面我們提佛那個(gè)一個(gè)名字daysAgo饥臂,意思就是在模板中可以直接通過(guò)使用這個(gè)名字作為關(guān)鍵字來(lái)使用這個(gè)管道逊躁。使用管道的時(shí)候,永遠(yuǎn)都需要傳入數(shù)據(jù)隅熙,然后數(shù)據(jù)都會(huì)被傳入transform函數(shù)也就是上面的value稽煤。我們會(huì)把我們的照片對(duì)象的Date對(duì)象傳入到這個(gè)管道,這就是我們這里要做的囚戚。同時(shí)注意可以通過(guò)管道傳入額外的參數(shù)酵熙,也就是我們?yōu)槭裁从?em>args?,因?yàn)檫@不是強(qiáng)制要求傳入的參數(shù)驰坊。
首先我們來(lái)一點(diǎn)數(shù)學(xué)魔法得出照片上幾天之前拍攝的匾二,(Stack Overflow也有這個(gè),我的解決方式可能比他丑點(diǎn)兒)拳芙,然后返回他察藐。返回的值就是將被渲染到模板上去的內(nèi)容。
如果你還記得之前的課的話舟扎,我們已經(jīng)在app.module.ts中設(shè)置好這個(gè)管道了分飞。
> 修改home.html中的photo項(xiàng)為如下:
<ion-item>
<img [src]="photo.image" />
<ion-badge item-right light>{{photo.date | daysAgo}} days ago</ion-badge>
</ion-item>
注意了(譯者敲了下黑板),我們加了這個(gè)句:
{{photo.date | daysAgo}}
這樣寫會(huì)把photo.date傳入到daysAgo管道睹限,然后將daysAgo返回的東西展示最這里譬猫。最終結(jié)果是一個(gè)帶有類似“5 天前”的徽章。
為所有照片創(chuàng)建一個(gè)Slideshow
我們已經(jīng)創(chuàng)建好了Slideshow的模板羡疗,所以現(xiàn)在我們需要制作一些邏輯來(lái)循環(huán)和展示所有照片染服,同時(shí)我們也要添加一個(gè)打開(kāi)slideshow的途徑(重啟途徑也要)。
我們還是先從playSlideshow函數(shù)開(kāi)始叨恨,這樣我們可以真正的打開(kāi)頁(yè)面柳刮。
> 修改 src/pages/home/home.ts的 playSlideshow 函數(shù)為如下:
playSlideshow(): void {
if(this.photos.length > 1){
let modal = this.modalCtrl.create(SlideshowPage, {photos:
this.photos});
modal.present();
} else {
let alert = this.simpleAlert.createAlert('Oops!', 'You need at least two photos before you can play a slideshow.');
alert.present();
}
}
跟創(chuàng)建警告提示框類似,我們給用戶撞見(jiàn)了一個(gè)模態(tài)框頁(yè)面。首先诚亚,我們創(chuàng)建了一個(gè)Modal,然后通過(guò)NavController呈現(xiàn)到用戶面前午乓。在這里站宗,我們使用已經(jīng)創(chuàng)建好的SlideshowPage來(lái)創(chuàng)建模態(tài)框,也將所有的照片數(shù)據(jù)傳入進(jìn)去益愈。這樣我們可以在Slideshow頁(yè)面上獲取到這些數(shù)據(jù)梢灭。
注意,我們只有在用戶有超過(guò)1張照片的時(shí)候才會(huì)觸發(fā)他(因?yàn)闆](méi)有或者只有1張照片的slideshow就不是真的slideshow了蒸其,對(duì)吧敏释?),否則會(huì)顯示警告提示框摸袁。
現(xiàn)在钥顽,我們來(lái)定義Slideshow頁(yè)的類定義。這個(gè)類挺小的靠汁,所以先全部貼出來(lái)蜂大,然后分段講解。
> 修改 src/pages/slideshow/slideshow.ts 為如下:
import { NavParams, ViewController } from 'ionic-angular';
import { Component, ElementRef, ViewChild } from '@angular/core';
@Component({
selector: 'page-slideshow',
templateUrl: 'slideshow.html'
})
export class SlideshowPage {
@ViewChild('imagePlayer') imagePlayer: ElementRef;
imagePlayerInterval: any;
photos: any;
constructor(public navParams: NavParams, public viewCtrl: ViewController) {
this.photos = this.navParams.get('photos');
}
ionViewDidEnter(){
this.playPhotos();
}
closeModal(){
this.viewCtrl.dismiss();
}
playPhotos(){
let imagePlayer = this.imagePlayer.nativeElement;
let i = 0;
//Clear any interval already set
clearInterval(this.imagePlayerInterval);
//Restart
this.imagePlayerInterval = setInterval(() => {
if(i < this.photos.length){
imagePlayer.src = this.photos[i].image;
i++;
}
else {
clearInterval(this.imagePlayerInterval);
}
}, 500);
}
}
這里有些東西可能你不大熟悉蝶怔。我們導(dǎo)入了NavParams服務(wù)可以用他拿到在創(chuàng)建的時(shí)候傳過(guò)來(lái)的數(shù)據(jù)奶浦。你可以看到我們?cè)跇?gòu)造器里面通過(guò)this.navParams.get('photos');獲取數(shù)據(jù)。這里另一個(gè)奇怪的東西是ViewController踢星。我們需要用到這個(gè)來(lái)隱藏模態(tài)框(我們這里定義了一個(gè)closeModal函數(shù)提供給模板里面的按鈕使用)澳叉。
這里最重要的函數(shù)是playPhotos,這就是我們循環(huán)所有照片然后在頁(yè)面上相應(yīng)改變對(duì)于的圖片元素的地方沐悦。首先成洗,我們通過(guò)之前設(shè)置好的@ViewChild引用得到圖片元素(之前模板里面通過(guò) #本地變量 的方式定義的)的引用,我們清理了當(dāng)前正在運(yùn)行的所有定時(shí)器(防止用戶在slideshow還在播放的時(shí)候突然重啟slideshow)藏否。然后我們開(kāi)始循環(huán)this.photos里的照片泌枪。如果還剩下照片可以展示,圖片的src屬性將會(huì)使用下一張照片的數(shù)據(jù)更新秕岛,如果沒(méi)有的話碌燕,就會(huì)清理計(jì)時(shí)器。上面代碼中继薛,定時(shí)器的間隔是500毫秒修壕,也就是0.5秒,我們可以根據(jù)個(gè)人喜好通過(guò)調(diào)整這個(gè)數(shù)值來(lái)調(diào)整slideshow的快和慢遏考。(甚至給用戶提供選擇來(lái)控制)
playPhotos函數(shù)上ionViewDidEnter函數(shù)自動(dòng)觸發(fā)的慈鸠,ionViewDisEnter函數(shù)上在進(jìn)入視圖的時(shí)候自動(dòng)執(zhí)行的,這個(gè)函數(shù)在我們每次進(jìn)入視圖的時(shí)候都會(huì)執(zhí)行灌具。
總結(jié)
這是另一節(jié)比較小的課青团,但是這里講的東西都蠻酷的譬巫。至此,應(yīng)用的大部分主體功能都完成了督笆,我們只要加上一些邊邊角角就可以了芦昔。當(dāng)然,我們還是得梅花他娃肿,但是下節(jié)課我們要學(xué)習(xí)的是整合本地通知和社交分享功能咕缎。