[Ionic 2從入門到精通] 3.6 保存和加載數(shù)據(jù)

第六課:保存和加載數(shù)據(jù)

你知道什么是最煩惱的嗎?如果你創(chuàng)建了一大個待完成的checklist懒构,稍后回來的時候再用的時候,發(fā)現(xiàn)沒有了耘擂。嗯胆剧,這就是應(yīng)用當前的狀態(tài),所以我們將要給用戶提供一個保存用戶數(shù)據(jù)的途徑醉冤。
我們已經(jīng)為他做了一些架構(gòu)準備秩霍,我們訂閱了我們的Observable在每次數(shù)據(jù)變更的時候都調(diào)用了save函數(shù),我們只需要現(xiàn)在來實現(xiàn)這個函數(shù)就可以了蚁阳。
> 修改 src/pages/home/home.ts 里面的 save 方法:

save(): void {
    Keyboard.close();
    this.dataService.save(this.checklists);
}

如果你不健忘的話铃绒,早些時候我們已經(jīng)生成和導入了一個數(shù)據(jù)服務(wù),所以我們這里只需要調(diào)用他并傳入checklists數(shù)據(jù)螺捐。當然颠悬,我們目前還沒有實現(xiàn)這個數(shù)據(jù)服務(wù),所以他現(xiàn)在不會對數(shù)據(jù)做任何事情定血,我們現(xiàn)在就來彌補他赔癌。注意,我們也調(diào)用了Keyboard的close方法澜沟,由于會在任何數(shù)據(jù)項變更的時候調(diào)用save方法灾票,我們可以用他來在用戶添加或者編輯完數(shù)據(jù)之后確保鍵盤關(guān)閉。

保存數(shù)據(jù)

我們現(xiàn)在要給data.ts碼代碼了茫虽,讓他可以將傳入的任何數(shù)據(jù)保存到存儲里面去刊苍。實際上這個服務(wù)的代碼相當?shù)暮唵危覀儊砜纯矗?br> > 修改 src/providers/data.ts :

import { Storage } from '@ionic/storage';
import { Injectable } from '@angular/core';

@Injectable()
export class Data {
    constructor(public storage: Storage){
    }

    getData(): Promise<any> {
        return this.storage.get('checklists');
    }
    save(data): void {
        let saveData = [];
        //Remove observables
        data.forEach((checklist) => {
            saveData.push({
                title: checklist.title,
                items: checklist.items
            });
        });

        let newData = JSON.stringify(saveData);
        this.storage.set('checklists', newData);
    }
}

這里有個我們之前沒見過的導入:

import { Storage } from '@ionic/storage';

Storage是Ionic的統(tǒng)一存儲服務(wù)濒析,他負責使用最好的方式來存儲數(shù)據(jù)的同時提供了一個統(tǒng)一的API給供我們使用正什。
當在設(shè)備上運行的時候,如果SQLite插件是可用狀態(tài)的話(我們之前安裝過了)悼枢,他將會使用本地(native)SQLite數(shù)據(jù)庫來存儲數(shù)據(jù)埠忘。由于SQLite數(shù)據(jù)庫只在設(shè)備上可用脾拆,在SQLite不可用的情況下馒索,Storage也會用IndexedDB,WebSQL或者標準瀏覽器的localStorage名船。
盡可能使用SQLite绰上,因為基于瀏覽器的本地存儲不大可靠可以被操作系統(tǒng)默默的清理掉。如果你的數(shù)據(jù)可以被隨機清理掉的話顯然很不理想渠驼。
我們來看看getData函數(shù):

getData(): Promise<any> {
    return this.storage.get('checklists');
}

這個函數(shù)允許我們獲取最新的存儲數(shù)據(jù)蜈块,他會以Promise的方式返回數(shù)據(jù)。我們將此函數(shù)的返回的Promise的返回類型設(shè)置為<any>類型,這是一個更復雜的類型百揭。記住爽哎,這不是唯一可用類型,所以器一,如果你覺得很迷惑的話课锌,你可以什么都不加,像這樣:

getData(){
    return this.storage.get('checklists');
}

注意祈秕,在這里我們沒有給promise完成的時候添加處理器渺贤,我們只是返回get方法的結(jié)果(一個解析當前存儲數(shù)據(jù)的promise)剑按。記住庆揩,這個行為不是瞬間完成的傅物,這樣我們可以在調(diào)用這個函數(shù)的任何地方添加處理器瘫筐,也更像應(yīng)用的工作流鼠冕。(希望這個能夠更簡單明了)
然后筏养,我們來到了saveData函數(shù)都弹,這個函數(shù)用于將數(shù)據(jù)保存到存儲里:

save(data): void {
    let saveData = [];

    //Remove observables
    data.forEach((checklist) => {
        saveData.push({
            title: checklist.title,
            items: checklist.items
        });
    });

    let newData = JSON.stringify(saveData);
    this.storage.set('checklists', newData);
}

之前提到我們仁锯,我們將數(shù)據(jù)存為一個簡單的JSON編碼字符串仙蚜,所以我們調(diào)用了JSON.stringify函數(shù)然后使用set方法將他保存到存儲對象里去玻孟。在做這些之前,我們把數(shù)據(jù)的observable移除掉只加入title和items鳍征,因為他們跟JSON不搭調(diào)(他會引起circular對象錯誤)黍翎,我們后面會重新創(chuàng)建它們。
這就是保存數(shù)據(jù)的全部內(nèi)容艳丛,也沒那么復雜匣掸。我們接下來處理加載數(shù)據(jù)到應(yīng)用中。

加載數(shù)據(jù)

任何時候當用戶打開應(yīng)用氮双,我們都需要從存儲中加載checklists數(shù)據(jù)碰酝,所以最適合做這個操作的地方是home頁的ionViewDidLoad,這個函數(shù)會在頁面加載完成的時候觸發(fā)戴差。我們將對構(gòu)造器進行小小的變更送爸。
> 在 src/pages/home/home.ts 中修改constructor和ionViewDidLoad:

constructor(public nav: NavController, public dataService: Data, public
alertCtrl: AlertController, public platform: Platform) {
}
ionViewDidLoad(){
this.platform.ready().then(() => {
    this.dataService.getData().then((checklists) => {

        let savedChecklists: any = false;

        if(typeof(checklists) != "undefined"){
            savedChecklists = JSON.parse(checklists);
        }
        if(savedChecklists){
            savedChecklists.forEach((savedChecklist) => {
                let loadChecklist = new ChecklistModel(savedChecklist.title, savedChecklist.items);
                this.checklists.push(loadChecklist);
                loadChecklist.checklist.subscribe(update => {
                    this.save();
                });
            });
        }
    });
});
}

我們調(diào)用了數(shù)據(jù)服務(wù)里面剛定義的getData函數(shù)。之前也提過暖释,getData函數(shù)返回一個promise而不是直接返回數(shù)據(jù)袭厂,這樣我們可以在加載完成之后處理響應(yīng)。如果getData直接返回數(shù)據(jù)的話球匕,當我們想要訪問他的時候可能他都沒有返回纹磺。
所以我們一直等待取回數(shù)據(jù),然后將checklists傳入到我們的處理器亮曹。首先我們解碼JSON字符串到數(shù)組到這樣我們就可以用來橄杨,然后我們循環(huán)數(shù)組里的每個數(shù)據(jù)項秘症,基于這些數(shù)據(jù)創(chuàng)建一個新的Checklist Data。循環(huán)數(shù)據(jù)和創(chuàng)建新的模型而不是直接將this.checklists設(shè)置為savedChecklists的原因是在保存checklists將他轉(zhuǎn)換成JSON字符串的時候他就喪失了使用數(shù)據(jù)模型里的助理函數(shù)的能力式矫。所以乡摹,我們得利用取得的標題和數(shù)據(jù)項來為所有的checklists創(chuàng)建新的對象。
最后采转,我們重新給Observable設(shè)置監(jiān)聽器趟卸,這樣當數(shù)據(jù)改變的時候就會被處罰。重點關(guān)注我們所作的這些都是在platform.ready()調(diào)用里面進行的氏义,如果在設(shè)備準備好之前這么做的話將會發(fā)生問題锄列。

總結(jié)

這就是本節(jié)課的所有內(nèi)容,數(shù)據(jù)現(xiàn)在在進行任何變更后可以被保存到SQLite數(shù)據(jù)里面去惯悠,應(yīng)用重新打開的時候邻邮,所有數(shù)據(jù)將會重新加載回來。試一下添加一些checklist或者修改checklist的狀態(tài)克婶,然后重新加載應(yīng)用看看對他進行的變更是否還在筒严。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市情萤,隨后出現(xiàn)的幾起案子鸭蛙,更是在濱河造成了極大的恐慌,老刑警劉巖筋岛,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娶视,死亡現(xiàn)場離奇詭異,居然都是意外死亡睁宰,警方通過查閱死者的電腦和手機肪获,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柒傻,“玉大人孝赫,你說我怎么就攤上這事『旆” “怎么了青柄?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長预侯。 經(jīng)常有香客問我致开,道長,這世上最難降的妖魔是什么雌桑? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任喇喉,我火速辦了婚禮祖今,結(jié)果婚禮上校坑,老公的妹妹穿的比我還像新娘拣技。我一直安慰自己,他們只是感情好耍目,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布膏斤。 她就那樣靜靜地躺著,像睡著了一般邪驮。 火紅的嫁衣襯著肌膚如雪莫辨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天毅访,我揣著相機與錄音沮榜,去河邊找鬼。 笑死喻粹,一個胖子當著我的面吹牛蟆融,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播守呜,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼型酥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了查乒?” 一聲冷哼從身側(cè)響起弥喉,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎玛迄,沒想到半個月后由境,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡蓖议,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年藻肄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拒担。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡嘹屯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出从撼,到底是詐尸還是另有隱情州弟,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布低零,位于F島的核電站婆翔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏掏婶。R本人自食惡果不足惜啃奴,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雄妥。 院中可真熱鬧最蕾,春花似錦依溯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至醋拧,卻和暖如春慷嗜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丹壕。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工庆械, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人菌赖。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓干奢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盏袄。 傳聞我的和親對象是個殘疾皇子忿峻,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容