2018年5月19日土曜日

underscore.js を QML で使う方法


Underscore.js から Development Version をダウンロードし GitHub - diro/qml_underscorejs: Underscore.js for QML を参考にして以下の修正をします。QML では JavaScript のグローバル変数を追加できなくしているので Qt グローバルオブジェクトに JavaScript プロパティー _ を追加して underscore.js の機能を使うようにしています。
underscore.js 修正差分:

--- original/underscore.js       2018-06-10 11:36:50.000000000 +0900
+++ scripts/underscore.js     2018-06-10 14:06:35.000000000 +0900
@@ -1,9 +1,10 @@
+.pragma library
 //     Underscore.js 1.9.1
 //     http://underscorejs.org
 //     (c) 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 //     Underscore may be freely distributed under the MIT license.

-(function() {
+var init = function() {

   // Baseline setup
   // --------------
@@ -56,7 +57,12 @@
     }
     exports._ = _;
   } else {
+    if (typeof Qt !== 'undefined') {
+      Qt._ = _;
+    }
+    else {
     root._ = _;
+    }
   }

   // Current version.
@@ -1689,4 +1695,8 @@
       return _;
     });
   }
-}());
+}
+
+if (typeof Qt !== 'undefined') {
+  init();
+}
メイン QML で修正した underscore.js をインポートし、ルートオブジェクトで var 型のプロパティー _ を定義して Qt._ で初期化すればアプリケーション全体で通常の underscore.js と同じ使い方ができます。
now.qml:
import QtQml 2.8
import "underscore.js" as Underscore

QtObject {
    readonly property var _: Qt._

    Component.onCompleted: {
        const times = _.chain(_.times(10000, _.now));
        print(times.first(), times.last());

        Qt.quit();
    }
}
実行結果です。
$ qml now.qml
qml: 1526710520747 1526710520748
$