angular - SQLite Mocking 不适用于 ionic

标签 angular sqlite typescript ionic-framework

我的 SQLiteMock 提供程序未被接收时遇到问题。我究竟做错了什么。我的理解是,当我使用“{ provide: SQLite, useClass: SQLiteMock }”时,应该使用 SQLiteMock 类而不是 SQLite。但是,除非我专门进入 Techdao.ts 并明确说要使用 SQLiteMock,然后将其而不是 SQLite 传入,否则我不会遇到这种情况。我错过了什么或做错了什么?

我正在使用 Ionic 3。

app.module.ts

import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { SQLite, SQLiteDatabaseConfig } from '@ionic-native/sqlite';
import { MyApp } from './app.component';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { Page1 } from '../pages/page1/page1';

declare var SQL;
class SQLiteMock {
    public create(config: SQLiteDatabaseConfig): Promise<SQLiteObject> {
        console.log("Create Mock SQLite Database.");
        var db = new SQL.Database();
        return new Promise((resolve, reject) => {
            resolve(new SQLiteObject(db));
        });
    }
}

class SQLiteObject {
    _objectInstance: any;
    constructor(_objectInstance: any) {
        this._objectInstance = _objectInstance;
    };
    public create(config: SQLiteDatabaseConfig): Promise<SQLiteObject> {
        var db;

        console.log("Open Mock SQLite Database.");
        var storeddb = localStorage.getItem("database");

        var arr = storeddb.split(',');
        if (storeddb) {
            db = new SQL.Database(arr);
        }
        else {
            db = new SQL.Database();
        }

        return new Promise((resolve, reject) => {
            resolve(new SQLiteObject(db));
        });
    }
    executeSql(statement: string, params: any): Promise<any> {
        console.log("Mock SQLite executeSql: " + statement);

        return new Promise((resolve, reject) => {
            try {
                var st = this._objectInstance.prepare(statement, params);
                var rows: Array<any> = [];
                while (st.step()) {
                    var row = st.getAsObject();
                    rows.push(row);
                }
                var payload = {
                    rows: {
                        item: function (i) {
                            return rows[i];
                        },
                        length: rows.length
                    },
                    rowsAffected: this._objectInstance.getRowsModified() || 0,
                    insertId: this._objectInstance.insertId || void 0
                };

                //save database after each sql query 
                var arr: ArrayBuffer = this._objectInstance.export();
                localStorage.setItem("database", String(arr));
                resolve(payload);
            } catch (e) {
                reject(e);
            }
        });
    };
}

@NgModule({
  declarations: [
    MyApp,
    Page1
  ],
  imports: [
      BrowserModule,
      HttpModule,
      IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    Page1
  ],
  providers: [
      StatusBar,
      Splashscreen,
      { provide: SQLite, useClass: SQLiteMock },
      { provide: ErrorHandler, useClass: IonicErrorHandler }
  ]
})
export class AppModule { }`

app.component.ts

import { Component, ViewChild } from '@angular/core';
import { Nav, Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  @ViewChild(Nav) nav: Nav;

  rootPage: any = Page1;

  public sqlstorage: SQLite;
  techdao: TechDAO;

  pages: Array<{title: string, component: any}>;

  constructor(public platform: Platform) {
      console.log("Platforms: " + platform.platforms());
      this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();

      this.initializeSQLite();

      Splashscreen.hide();

    });
  }

  initializeSQLite() {
      this.sqlstorage = new SQLite();
      this.techdao = new TechDAO(this.sqlstorage);

      this.techdao.createTables(); 
  }

  openPage(page) {
    // Reset the content nav to have just this page
    // we wouldn't want the back button to show in this scenario
    this.nav.setRoot(page.component);
  }  
}

techdao.ts

import { SQLite, SQLiteDatabaseConfig, SQLiteObject } from '@ionic-native/sqlite';

export class TechDAO {
    sqlite: any;
    db: SQLiteObject;

    constructor(private _sqlite: SQLite) {
        this.sqlite = _sqlite;
    };

    public createTables() {
        this.sqlite.create({
            name: 'tech.db',
            location: 'default'
        }).then((_db: SQLiteObject) => {
            console.log("Create Database tables if they don't exist.");
            this.db = _db;

            this.createAppointmentTable();
        }).catch(e => console.log(e));  
    }

    createAppointmentTable() {
        this.db.executeSql(
            'create table if not exists appointment(' +
            'ticketnumber TEXT PRIMARY KEY,' +
            'customername TEXT,' +
            'contactemail TEXT,' +
            'contactphone TEXT' +
            ')', {})
            .then(() => console.log('Executed SQL - Create Appointment Table'))
            .catch(e => console.log(e));
    }    
}

最佳答案

你快到了。

添加 { provide: SQLite, useClass: SQLiteMock } 是不够的。

您需要导入并使用您自己的SQLiteMock,而不是标准库。

因此,如果您有以下 Camera 模拟:

import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';

import { Camera } from '@ionic-native/camera';

class CameraMock extends Camera {
  getPicture(options) {
    return new Promise((resolve, reject) => {
      resolve("BASE_64_ENCODED_DATA_GOES_HERE");
    })
  }
}

@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [
    {provide: ErrorHandler, useClass: IonicErrorHandler},
    { provide: Camera, useClass: CameraMock }
  ]
})
export class AppModule {}

然后在另一个 .ts 文件中,否则您将使用 Camera,您必须改用自己的 CameraMock

import { CameraMock } from "../mocks/camera-mock";

完成该功能的开发后,编辑您的代码以切换回使用实际的相机。您甚至可以巧妙地利用环境变量为开发和生产构建使用不同的库。

关于angular - SQLite Mocking 不适用于 ionic ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44571246/

相关文章:

Angular 4 在 angular-cli 中切换样式表

mysql - 如何在 super 查询中使用子查询的结果?

typescript - VueJS + Typescript + 动态导入

typescript - 如何检查字符串是否仅包含空格或在 TypeScript 中为空?

angular - 没有提供带有 Angular 2 和 Http 服务的 XHRBackend

javascript - Angular 应用程序中函数运行时传递的值不可用

html - 在占位符文本之前使用图标搜索输入 - Material Design

android - 删除索引无法正常工作的SQlite Android

php - 如何从打开的连接确定 SQLite 文件名?

javascript - 类似于 typescript 中的字符串枚举类型