Web SQL DatabaseでexecuteSqlした後に何か処理する
前回の記事の続きでWeb SQL Databaseを使ってみた。
が、executeSqlでselectを実行する際、その結果はコールバックで受け取る必要があるのでここもネックになってます。
不都合があったのでその対応メモ。
monacaアプリの中でAngularJSを使ってます。
対応
1,2が非同期処理なので、何も考えずに書くと1→2の処理順が担保されません。
なので1,2はpromiseを使って同期しちゃう。3は2の中に入れちゃう。
module.controller('AppController', function($scope) { // DB生成 var createDatabase = function(){ return new Promise(function(resolve, reject) { // タイムアウト値の設定は任意 setTimeout(function(){ console.log('Start createDatabase'); var db = window.openDatabase("Database", "1.0", "TestDatabase", 200000); if(db.version == ""){ console.log('not exist db'); // DB無いので作ります db.transaction( function(tx){ tx.executeSql('DROP TABLE IF EXISTS TestTable'); tx.executeSql('CREATE TABLE IF NOT EXISTS TestTable (id unique, name)'); // テストデータを叩き込む tx.executeSql('INSERT INTO TestTable VALUES (1,"てすとでーた")'); }, function(){ // 失敗時 }, function(){ // 成功時 } ); }else{ console.log('exist db'); } console.log('End createDatabase'); resolve(); },100); }); }; // 検索 var selectDatabase = function(){ return new Promise(function(resolv,reject){ setTimeout(function(){ console.log('Start selectDatabase'); var db = window.openDatabase("Database","1.0","TestDatabase",200000); db.transaction( function(transaction){ transaction.executeSql('SELECT * FROM TestTable', [], querySuccess, errorCB); }, function(){ // 失敗時 }, function(){ // 成功時 } ); console.log('End selectDatabase'); },100); var querySuccess = function(tx,results){ console.log('Start query'); // ************************* // クエリ成功時の処理をかく(results → testdata) // ************************* // scopeの更新と反映 $scope.testdata = testdata; $scope.$apply(); // ★ console.log('End query'); resolve(); }; var errorCB = function(err) { console.log("Error occured while executing SQL: "+err.code); } }); }; createDatabase().then(selectDatabase); });
やりたいことその2
- CRUD処理はfactoryでまとめたい(controllerに書きたくない)
- select処理の後、$scopeに値をセットし、$scope.apply()をしたい(上記★の箇所)
つまりselect → 結果をセット → 反映の順番を担保したい
ということでCRUDはfactoryで書こうと思ったのですが問題が。。。
問題箇所
いろいろ試した結果、factory経由で$scopeの値をコントローラ間で引き継ぐことはできるが、factory内で$scope.apply()が効かなそう(合ってるのかな?)
とはいえ、factoryの処理(ex. select処理)完了を待ってcontroller側の処理($scope.apply())を行えれば良いので、factory側の処理とcontrollerで同期したいところですが、うまい方法が見つからず(›´ω`‹ )
機能的にはlocal storageでも問題無いのでそちらに移行しようか検討中