2017-06-15 68 views
2

我遇到了SQLiteMock提供程序未收到問題。我究竟做錯了什麼。我的理解是,當我使用「{提供:SQLite,useClass:SQLiteMock}」時,應該使用SQLiteMock類而不是SQLite。但是,我沒有遇到這種情況,除非我專門進入Techdao.ts並明確聲明使用SQLiteMock,然後將其傳入而不是SQLite。我錯過了什麼或做錯了什麼?SQLite嘲笑不在離子中工作

我使用的離子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)); 
    }  
} 

回答

1

你快到了。

僅添加{ 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"; 

當您使用該功能的開發完成,編輯代碼切換回使用實際Camera。你甚至可以用環境變量做一些聰明的技巧來爲dev和prod構建使用不同的庫。

+0

嗯,好的,所以我最初實際上是在那裏。我已經在SQLite將被使用的地方輸入了我的SQLiteMock。我希望能夠在SQLite中替換掉SQLite的SQLiteMock,當我不在開發版中並轉移到prod版本或UAT版本時。 – Adam

+0

這超出了你原來的問題範圍。在任何情況下,正如我所說的,你可以使用angular的函數isDevMode(),並在每種情況下使用不同的lib(SQLite或SQLiteMock)。如果一個功能足夠小,我更願意在完成時將所有的輸入全部交換,但是你也可以做。 – maninak

+0

謝謝你的幫助!我非常感謝它,並且isDevMode()給了我另一個消息!謝謝! – Adam