Ionic 2 + LokiJS + LocalForage(渐进式 Web 应用程序、无 SQL 数据库和长期存储)
概括
在本指南中,我们将使用 LokiJS 数据库和 LocalForage 构建一个 Ionic 2 应用,用于持久存储。不过,我的应用不是普通的数据库相关应用。以下是我的应用要求:
- 非 SQL 数据库
- 长期数据持久化
- 代码简单易读,适配器尽可能少
- 平台无关
我选择 LokiJS 的主要原因
LokiJS 提供了一些独特的优势。
- 简单、熟悉的 JavaScript 对象
- lokijs.org上有很好的文档
- 内存架构
- 将完整数据库存储为 JSON 令牌的能力(对于小型数据库来说非常棒!)
- 微观足迹
我的 Ionic 2 环境
Ionic 2 正在快速成长和成熟。这是我用来创建本教程的环境。
Cordova 命令行:6.1.1
Ionic 框架版本:2.0.0-beta.9
Ionic CLI 版本:2.0.0-beta.25
Ionic App Lib 版本:2.0.0-beta.15
ios-deploy 版本:1.8.6
ios-sim版本:5.0.8
操作系统:Mac OS X El Capitan
节点版本:v5.7.1
Xcode 版本:Xcode 7.3 构建版本 7D175
生成初始代码库
在终端中输入命令
ionic start LokiDB blank --v2
cd LokiDB
ionic platform add ios
ionic platform add android
npm install lokijs
npm install localforage
如果您的 Ionic Framework 版本早于 beta 9,则需要在第一个命令中添加“--ts”:
ionic start LokiDB blank --v2 --ts
这些命令将构建我们的骨架应用程序。我们所有的黑客攻击都将在 app > pages > home > home.html和home.ts中进行。
添加不带持久性的 LokiJS
在home.ts中的import语句下,添加
declare var require: any; var loki = require('lokijs');
Inside the HomePage class, we need to declare 2 objects: one for our database and one for its collection of documents
db: any; // LokiJS database robots: any; // our DB's document collection object
Let's set up these objects inside the constructor
this.db = new loki('robotsOnTV'); this.robots = this.db.addCollection('robots');
Next, we'll insert a few documents (for those who aren't used to no-SQL databases, a document is just an object held by the database). We're using JSON-style insertion because LokiJS receives the data as JSON. Don't worry about creating TypeScript interfaces because they will only increase the amount of code we need to write.
this.robots.insert({ name: 'Bender', tvShow: 'Futurama' }); this.robots.insert({ name: 'Rosie', tvShow: 'The Jetsons' }); this.robots.insert({ name: 'K1', tvShow: 'Dr. Who' });
The final thing to do in the TS file is to add a helper function. We want the HTML file to display these results, but *ngFor will not iterate over custom data types. As a result, we're going to write a simple, generic object-to-Array function:
convert2Array(val) { return Array.from(val); }
This is how your home.ts should look:
import {Component} from "@angular/core"; import {NavController} from 'ionic-angular'; declare var require: any; var loki = require('lokijs'); @Component({ templateUrl: 'build/pages/home/home.html' }) export class HomePage { db: any; // LokiJS database robots: any; // our DB's document collection object constructor(private navController: NavController) { this.db = new loki('robotsOnTV'); this.robots = this.db.addCollection('robots'); this.robots.insert({ name: 'Bender', tvShow: 'Futurama' }); this.robots.insert({ name: 'Rosie', tvShow: 'The Jetsons' }); this.robots.insert({ name: 'K1', tvShow: 'Dr. Who' }); } convert2Array(val) { return Array.from(val); } }
Lastly, let's get the HTML ready. Delete everything inside the <ion-content> tag of home.html, and replace it with this:
<!-- list all database elements --> <ion-card *ngFor="let robot of convert2Array(robots.data)"> <ion-card-header> {{robot.name}} </ion-card-header> <ion-card-content> {{robot.tvShow}} </ion-card-content> </ion-card>
向我们的 LokiJS 数据库添加交互元素
在home.ts中,添加 2 个变量用于用户输入。我们将它们命名为robotName和robotTVShow。
robotName: string; robotTVShow: string;
We'll add in support to insert and delete from the database as well:
addDocument() { if (!this.robotName || !this.robotTVShow) { console.log("field is blank..."); return; } this.robots.insert({ name: this.robotName, tvShow: this.robotTVShow }); // LokiJS is not zero-indexed, so the final element is at <length>, not <length - 1> console.log("inserted document: " + this.robots.get(length)); console.log("robots.data.length: " + this.robots.data.length); } deleteDocument($event, robot) { console.log("robot to delete: name = " + robot.name + ", TV show = ", robot.tvShow); // $loki is the document's index in the collection console.log("targeting document at collection index: " + robot.$loki); this.robots.remove(robot.$loki); }
Let's add one more card to home.html.
<!-- add items to LokiJS database --> <ion-card> <ion-card-content> <ion-list> <ion-item> <ion-label floating>Robot Name</ion-label> <ion-input clearInput [(ngModel)]="robotName"></ion-input> </ion-item> <ion-item> <ion-label floating>Which TV Show?</ion-label> <ion-input type="text" [(ngModel)]="robotTVShow"></ion-input> </ion-item> </ion-list> </ion-card-content> <ion-card-content> <button (click)="addDocument()">Add</button> </ion-card-content> </ion-card>
Finally, we need to allow for document deletion. Let's change the original card so that we have a Delete button:
<!-- list all database elements --> <ion-card *ngFor="let robot of convert2Array(robots.data)"> <ion-card-header> {{robot.name}} </ion-card-header> <ion-card-content> {{robot.tvShow}} <button (click)="deleteDocument($event, robot)">Delete</button> </ion-card-content> </ion-card>
添加 LocalForage 进行长期存储
我们将允许保存到文件并从该文件导入。有关 LocalForage 如何确定存储优先级的更多信息,请参阅https://mozilla.github.io/localForage/
home.ts需要一个 localForage 对象。将其添加到var loki = ...代码下方:
var localforage = require('localforage');
Add in functions for saving the database and retrieving it. LocalForage uses key-value maps, and since we're only interested in saving a single value (the entire database), we'll hard-code our key as storeKey.
saveAll() { localforage.setItem('storeKey', JSON.stringify(this.db)).then(function (value) { console.log('database successfully saved'); }).catch(function(err) { console.log('error while saving: ' + err); }); } importAll() { var self = this; localforage.getItem('storeKey').then(function(value) { console.log('the full database has been retrieved'); self.db.loadJSON(value); self.robots = self.db.getCollection('robots'); // slight hack! we're manually reconnecting the collection variable }).catch(function(err) { console.log('error importing database: ' + err); }); }
In home.html, we're going to hook up the new storage functions to 2 new buttons. Next to our "Add" button, include these:
<button (click)="saveAll()">Save All</button> <button (click)="importAll()">Import All</button>
That's all it takes to build a persistent, no-SQL database in Ionic 2!
I hope you found this tutorial informative and enjoyable. Thank you for reading!
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~