带 ionic 2 的 cordova s​​qlite 插件:"new transaction is waiting for open operation"

cordova sqllite plugin with ionic 2 giving : "new transaction is waiting for open operation"

我正在尝试创建数据库服务。正在从 app.ts 调用 initializeDb 函数。 provider/data/data.ts 的片段就像​​

import {Injectable} from 'angular2/core';
import {Platform, Storage, SqlStorage} from 'ionic-angular';

@Injectable()
export class Data {
  dbHandle;
  platform;

  constructor(platform: Platform) {
    this.platform = platform;
  }
  public initializeDataService() {
    this.platform.ready().then(() => {
      console.log('initializing db');
      this.dbHandle = new Storage(SqlStorage);
      this.dbHandle.query('CREATE TABLE IF NOT EXISTS APP_DATA (KEY_NAME TEXT PRIMARY KEY, KEY_VALUE TEXT)').
        then((data) => { console.log('Table created succesfully' + JSON.stringify(data)); return; },
        (error) => { console.log('Error while creating table: ' + JSON.stringify(error)); return; });
    });
  }
  getRecord(key_name) {
    let result = {};
    console.log('trying to get record for ' + key_name);
    this.dbHandle.query("SELECT * FROM APP_DATA WHERE KEY_NAME = '" + key_name + "'").
      then((data) => {
        console.log('Data obtained from db is ' + JSON.stringify(data));
        if (data.res.rows.length > 0) {
          return data.res.rows.item(0);
        }
        else {
          return result;
        }
      },
      (error) => {
        console.log('Error while selecting record for ' + key_name + ' error is: ' + JSON.stringify(error));
        return result;
      });
    console.log('This should have never been reached');
  }
}

另一页,即。登录看起来像:

import {Platform, Page, NavController} from 'ionic-angular';
import {Http, Headers} from 'angular2/http';
import {Data} from '../../providers/data/data';
@Page({
  templateUrl: 'build/pages/login/login.html',
})
export class LoginPage {
  platform;
  constructor(platform: Platform, private data: Data, private http: Http) {
    this.platform = platform;
    this.platform.ready().
      then(() => {
        this.checkLogin();
      });  
  }
  checkLogin() {
    this.platform.ready().
      then(() => {
        this.loginRec = this.data.getRecord('LOGIN_REC');
        console.log('Login Rec from DB is '+JSON.stringify(this.loginRec));
        if ({} == this.loginRec) {
          // take to sign-up
          console.log('No local login rec present');
        }
        else {
          // try to do specific login
          console.log('Somethign present');
        }
      },
      (error) => {
        console.log('LoginPage: Platform not yet ready');
      });
  };
}

现在这是日志的快照:

1     414909   log      Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
2     415686   log      LoginPage
3     416134   log      Inside app.ts
4     416136   log      initializing db
5     416144   log      OPEN database: __ionicstorage
6     416156   log      new transaction is waiting for open operation
7     416158   log      new transaction is waiting for open operation
12    416175   log      Login Rec from DB is undefined
8     416160   log      Returning db handle
9     416166   log      trying to get record for LOGIN_REC
10    416169   log      new transaction is waiting for open operation
11    416173   log      This should have never been reached
14    416195   log      DB opened: __ionicstorage
13    416179   log      Somethign present
15    416229   log      Table created succesfully{"tx":{"db":{"openargs":{"name":"__ionicstorage","location":2,"createFromLocation":0,"backupFlag":2,"existingDatabase":false,"dblocation":"nosync"},"dbname":"__ionicstorage"},"txlock":true,"readOnly":false,"executes":[],"finalized":true},"res":{"rows":{"length":0},"rowsAffected":0}}
16    416250   log      Data obtained from db is {"tx":{"db":{"openargs":{"name":"__ionicstorage","location":2,"createFromLocation":0,"backupFlag":2,"existingDatabase":false,"dblocation":"nosync"},"dbname":"__ionicstorage"},"txlock":true,"readOnly":false,"executes":[],"finalized":true},"res":{"rows":{"length":0},"rowsAffected":0}}

从日志来看,似乎正在后台打开数据库并继续执行。 所有的数据库操作似乎都在排队,直到数据库打开

我想要的是打开数据库,只有在成功打开后才能进行所有其他操作。为此,我总是 promise/then 有所帮助。日志表明并非如此。

任何关于如何实现这一目标的pointers/suggestion表示赞赏

提前致谢

~达瓦尔

这可能不是一个合适的解决方案,但以下确实对我有用。

1。我将 Data 作为提供者放入我的 app.ts

2。将主页设为中间根页面(而不是 loginPage)

@App({
  template: '<ion-nav [root]="rootPage"></ion-nav>',
  providers: [Data],
  config: {} // http://ionicframework.com/docs/v2/api/config/Config/
})
export class MyApp {
  platform;
  rootPage;
  constructor(platform: Platform, private data : Data) {
    console.log('app.ts constructor');
    this.platform = platform;
    this.initializeApp(data);
    this.rootPage = HomePage;
  }
  initializeApp(data) {
    this.platform.ready().then( () => {
    console.log('Inside app.ts');
    });
  }
}

3。在主页中仅在 deviceRead

上导航至 LoginPage
this.platform.ready().
then(() => {
console.log('HomePage: Platform ready');
this.nav.push(LoginPage);
});

4。将 data.ts 中的 getRecord 函数重构为 return promise

getRecord(key_name) {
  let result = {};
  return new Promise( (resolve, reject) => {
    this.dbHandle.query("SELECT * FROM APP_DATA WHERE KEY_NAME = '" + key_name + "'")
    .then((data) => {
      console.log('Data obtained from db is ' + JSON.stringify(data));
      if (data.res.rows.length > 0) {
        console.log('Something is present');
        resolve(data.res.rows.item(0));
      }
      else{
        console.log('Sending back empty record');
        resolve(result);
      }
    },
    (error) => {
      console.log('Error while selecting record for ' + key_name + ' error is: ' + JSON.stringify(error));
      reject(error);
    });
  });
}

5。最后检查 login.ts 中的承诺为:

this.data.getRecord('LOGIN_REC').
  then((data) => {
    console.log('Login Rec from DB is ' + JSON.stringify(data));
    this.loginRec = data;
    if ({} == this.loginRec) {
      // take to sign-up
      console.log('No local login rec present');
    } else {
      // try to do specific login
      console.log('Somethign present');
    }
  }, (error) => {
    console.log('couldnt fetch record from db' + JSON.stringify(error))
});

您可以使用 observable 而不是 promise Angular 2.. 您必须像这样创建一个 observable:

 doSomeWork(){
   return Observable.create(observer => {
     //do some rest call or Database queries.
     observer.next(someResult);
     observer.complete();
   });
 }

并像这样订阅:

 this.doSomeWork().subscribe(data=>{
     // do something with the data
 });

这是一个可能适用于您的代码的代码片段(我没有检查格式)

    getRecord(key_name) {
        let result = {};
        console.log('trying to get record for ' + key_name);
    return Observable.create(observer => {
        this.dbHandle.query("SELECT * FROM APP_DATA WHERE KEY_NAME = '" + key_name + "'").then((data) => {
            console.log('Data obtained from db is ' + JSON.stringify(data));
            if (data.res.rows.length > 0) {
                observer.next(data.res.rows.item(0));
            }
            else {
               observer.next(result);
            }
            observer.complete();
         },(error) => {
            console.log('Error while selecting record for ' + key_name + ' error is: ' + JSON.stringify(error));
            observer.next(result);
            observer.complete();
         });
        console.log('This will never be reached');
   });
}

当您想获取记录时,您必须订阅您创建的可观察对象。

this.getRecord('LOGIN_REC').subscribe(data => {
        console.log("data",data);
});