LoginSignup
2
3

More than 5 years have passed since last update.

Cordova(PhoneGap)上で jQueryMobile と RequireJS を組み合わせてみた

Posted at

GitHub サンプル

Cordova の上で jQuery Mobile と RequireJS を組み合わせて使えるか試した。
一応動いた(ただし確認したのは Android だけ)。

データベースのところ特に力入れた。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="msapplication-tap-highlight" content="no" />
    <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
    <link rel="stylesheet" type="text/css" href="css/jquery.mobile.min.css" />
    <title>Hello World</title>
  </head>
  <body>
    <div data-role="page">
      <div data-role="header">
        <h1>header</h1>
      </div>
      <div role="main">
        <p id="console">
        </p>
      </div>
    </div>

    <script type="text/javascript" src="cordova.js"></script>
    <script type="text/javascript" src="js/lib/require.js" data-main="js/index"></script>
  </body>
</html>

普通に require.js を読み込んで、 data-mainindex.js を指定。

index.js
requirejs.config({
    paths: {
        'jquery': 'lib/jquery.min',
        'jquery-mobile': 'lib/jquery.mobile.min'
    }
});

require(['root', 'database', 'jquery-mobile'], function(root) {
    root.deviceready(function() {
        root.log('Hello Cordova with RequireJS!!');

        root.db.readTransaction(function(tx) {
            root.deferredTransaction(tx)
                .first('SELECT * FROM SAMPLE_TABLE')
                .done(function(exec, result) {
                    for (var i=0; i<result.rows.length; i++) {
                        var row = result.rows.item(i);
                        root.log('[database rows] id=' + row.ID + ', message=' + row.MESSAGE);
                    }
                });
        });
    });
});

先頭で jQueryjQuery Mobile のパスを定義して、
require() でデータベースの初期化をしているモジュール(database)と jquery-mobile を依存対象として定義。

root.js
define(['jquery'], function($) {
    return {
        log: function(message) {
            // weinre console is not work!!
            $('#console').append(message + '<br>');
            // console.log(message);
        },

        deviceready: function(callback) {
            var root = this;
            document.addEventListener('deviceready', function() {
                try {
                    callback();
                } catch (e) {
                    root.log('error : ' + e);
                }
            });
        },

        deferredTransaction: function(transaction) {
            var root = this;
            exec.first = executeSql;

            return exec;

            function exec(sql, params) {
                return function(exec, result) {
                    return exec.first(sql, params);
                };
            }

            function executeSql(sql, params) {
                var d = new $.Deferred();

                root.log('execute sql : ' + sql + ', params=' + params);

                transaction.executeSql(
                    sql,
                    params || [],
                    function(tx, result) {
                        d.resolve(root.deferredTransaction(tx), result);
                    },
                    function(tx, result) {
                        d.reject(root.deferredTransaction(tx), result);
                    }
                );

                return d.promise();
            }
        }
    };
});

root は、共通処理とかをまとめたオブジェクトを定義したモジュール。

標準のデータベース API はコールバック地獄必至なので、 jQuery の Deferred を使ってシンプルに書けるように頑張った(deferredTransaction())。

database.js
define(['root', 'jquery'], function(root, $) {
    root.deviceready(function() {
        root.log('initializing database...');

        root.db = openDatabase('sampledb', '', 'Sample Database', 1024 * 1024 * 10);

        root.db.transaction(
            function(tx) {
                var exec = root.deferredTransaction(tx);

                exec.first('DROP TABLE IF EXISTS SAMPLE_TABLE')
                    .then(exec('CREATE TABLE SAMPLE_TABLE (ID INTEGER PRIMARY KEY, MESSAGE)'))
                    .then(exec('INSERT INTO SAMPLE_TABLE (MESSAGE) VALUES (?)', ['Hoge']))
                    .then(exec('INSERT INTO SAMPLE_TABLE (MESSAGE) VALUES (?)', ['Fuga']))
                    .then(exec('INSERT INTO SAMPLE_TABLE (MESSAGE) VALUES (?)', ['Piyo']))
                    .then(exec('SELECT * FROM SAMPLE_TABLE'))
                    .then(function(exec, result) {
                        root.log('count=' + result.rows.length);
                        return exec.first('DELETE FROM SAMPLE_TABLE WHERE MESSAGE=?', ['Fuga']);
                    })
                    .done(function() {
                        root.log('success to initialize database');
                    })
                    .fail(function(exec, result) {
                        root.log('fail to initialize database : ' + JSON.stringify(result));
                    });
            },
            function(error) {
                root.log('fail to initialize database');
            });

    });
});

画面の様子

cordova_requirejs.png

結論: Deferred って素晴らしい。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3