Ionic 2 + LokiJS + LocalForage(渐进式 Web 应用程序、无 SQL 数据库和长期存储)

发布日期:2026-07-12 04:09:03   来源 : 杭州电子商务研究院    浏览量 :1
杭州电子商务研究院 发布日期:2026-07-12 04:09:03  
1

概括

在本指南中,我们将使用 LokiJS 数据库和 LocalForage 构建一个 Ionic 2 应用,用于持久存储。不过,我的应用不是普通的数据库相关应用。以下是我的应用要求:

  1. 非 SQL 数据库
  2. 长期数据持久化
  3. 代码简单易读,适配器尽可能少
  4. 平台无关

我选择 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.htmlhome.ts中进行

添加不带持久性的 LokiJS

  1. 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 数据库添加交互元素

  1. home.ts中,添加 2 个变量用于用户输入。我们将它们命名为robotNamerobotTVShow

    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/

  1. 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!

以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据