带有离子2的cordova s​​qllite插件:“新事务正在等待开放操作”

时间:2016-04-19 12:05:22

标签: sqlite cordova ionic2

我正在尝试创建数据库服务。从app.ts调用initializeDb函数。提供者/数据/ 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}}

从日志中可以看出,DB的打开正在后台进行并且执行继续进行。 所有数据库操作似乎都排队等到DB打开的时间

我想要的是打开数据库,只有在成功打开后才能执行所有其他操作。为此,我总是承诺/然后帮助。日志表明不然。

关于如何实现这一点的任何指示/建议

提前致谢

〜Dhaval

2 个答案:

答案 0 :(得分:0)

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

1。我在我的app.ts

中将Data作为提供者

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。在HomePage中,只导航到LoginPage

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

4。重构data.ts中的getRecord函数以返回一个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中检查promise:

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))
});

答案 1 :(得分:0)

你可以使用Angular 2的observable而不是promise。你必须创建一个这样的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');
   });
}

当你想要获得记录时,你必须订阅你创建的observable。

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