susunshunのお粗末な記録

お粗末に丁寧に生きる

Web SQL DatabaseでexecuteSqlした後に何か処理する

前回の記事の続きでWeb SQL Databaseを使ってみた。

susunshun.hatenablog.com


が、executeSqlでselectを実行する際、その結果はコールバックで受け取る必要があるのでここもネックになってます。

不都合があったのでその対応メモ。
monacaアプリの中でAngularJSを使ってます。

やりたいこと

  1. DBが無ければ生成
  2. DB検索
  3. 結果をscopeにぶちこむ
  4. バインド(自動)

の順で処理します。

対応

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でも問題無いのでそちらに移行しようか検討中

しかしmonaca IDEだとだいぶデバッグが辛いですね

余談

いまmonacaアプリはonsen UI + Angular1系で作ってるんですが、昨日Onsen UIがAngular2系に対応したとのこと!!
Angularは1と2で全く別物と聞いているので近いうちに試したいところ(どうせならIonic使いたい)

onsen.io