AngularJSを使ってWindowsストアアプリを作ってみる
このチュートリアルは、AngularJSを使ってWindowsストアアプリを使って作ってみます。
Part 1では、HelloWorld!を、Microsoft独自のJavaScriptのライブラリを実装したWinJSだけで作ってみました。
Part 2では、同じアプリをAngularJSで作ってみます。
Part 1のチュートリアルでは、Microsoftが出している HelloWorld!の事例をもとに、Microsoftが提供するWindowsストア用のJavaScriptライブラリ、WinJSだけでアプリだけで作ってみました。見かけはAngularJSっぽい動きにしましたが、ソースコードはAngularJS抜きで実現しました。
こんどは、早速、AngularJSで同じWindowsストアアプリに挑戦してみます。
MicrosoftのHelloWorld!の事例は、ユーザーが名前をInputフィールドに入れてボタンをクリックすると、Inputフィールドの下に「Hello ○○!」と表示されるものです。
そこの部分をAngularJSに置き換えて、Inputフィールドに何かを入力するたびに、Inputフィールドの下に入力した文字列を表示するようにしました。
完成したAngularJSでのHelloWorld!は次のような感じです:
default.htmlは、Part 1と比べて、3点ほど違いがありますが、ここでは default.html のソースコードをご覧になってください。
default.htmlのソースコードは次ぎのとおりです:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta charset="utf-8" />
<title>HelloWorldInAngularJS.Windows</title>
<!-- WinJS 参照 -->
<link href="//Microsoft.WinJS.2.0/css/ui-light.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.2.0/js/base.js"></script>
<script src="//Microsoft.WinJS.2.0/js/ui.js"></script>
<!-- HelloWorldInAngularJS.Windows 参照 -->
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/default.js"></script>
<!-- AngularJS 参照 -->
<script src="/js/angular.js"></script>
</head>
<body>
<h1 class="headerClass">Hello AngularJS!</h1>
<h1 class="headerClass">Hello Windows Store!</h1>
<div ng-app="" class="mainContent">
<p>お名前はなんですか?</p>
<input id="nameInput" type="text" ng-model="name" ng-init=" name = 'you'" />
<!--
<button id="helloButton">「こんにちは」と言って!</button>
<div id="greetingOutput"></div>
-->
<p>Hello, {{name}} !</p>
<br />
<label for="ratingControlDiv">
この挨拶を評価してください:
</label>
<div id="ratingControlDiv" data-win-control="WinJS.UI.Rating">
</div>
<div id="ratingOutput"></div>
</div>
</body>
</html>
AngularJSのライブラリを /js/ のディレクトリにコピーして、default.htmlの中で参照しました。
VisualStudioの**/js/**フォルダ:
<!-- AngularJS 参照 -->
<script src="/js/angular.js"></script>
理由は後でのべますが、ここでは、minified(圧縮)バージョンでは無く、圧縮されていないバージョンのライブラリをダウンロードしてください。
ダウンロードしたAngularJSのライブラリ(angular.js)を、そのまま使うと、VisualStudioでランタイムエラーが出ます。
このエラーは、「ダイナミック・コンテンツを追加できない(エラーコード:0x800c001c)」という内容です。エラーの理由は、AngularJSではダイナミックなコンテンツを扱う機能がありますが、Microsoftは、セキュリティを強化するために、信頼しないデータソース(この場合はAngularJS)には、それを許しません。
このエラーを回避するために、先ほどのangular.jsのソースコードをエディターで開いて、次ぎの2カ所修正します(これがminifiedバージョンを使わない理由です)。
修正箇所1:
修正前
append: function(element, node) {
forEach(new JQLite(node), function(child){
if (element.nodeType === 1 || element.nodeType === 11) {
element.appendChild(child);
}
});
},
修正後
append: function (element, node) {
MSApp.execUnsafeLocalFunction(function(){
forEach(new JQLite(node), function (child) {
if (element.nodeType === 1 || element.nodeType === 11) {
element.appendChild(child);
}
});
});
},
修正箇所2:
修正前
prepend: function(element, node) {
if (element.nodeType === 1) {
var index = element.firstChild;
forEach(new JQLite(node), function(child){
element.insertBefore(child, index);
});
}
},
修正後
prepend: function (element, node) {
MSApp.execUnsafeLocalFunction(function () {
if (element.nodeType === 1) {
var index = element.firstChild;
forEach(new JQLite(node), function (child) {
element.insertBefore(child, index);
});
}
});
},
このように、「危ない」と判断されるコードを、MSApp.execUnsafeLocalFunction()で囲むことにより、ランタイムエラーは出なくなります。
ソースコードの中に、AngularJSの構文を入れました(ng-app, ng-model, ng-init, {{name}})。ここではボタンは必要ないので、コメントにしました。
<div ng-app="" class="mainContent">
<p>お名前はなんですか?</p>
<input id="nameInput" type="text" ng-model="name" ng-init=" name = 'you'" />
<!--
<button id="helloButton">「こんにちは」と言って!</button>
<div id="greetingOutput"></div>
-->
<p>Hello, {{name}} !</p>
<br />
<label for="ratingControlDiv">
この挨拶を評価してください:
</label>
<div id="ratingControlDiv" data-win-control="WinJS.UI.Rating">
</div>
<div id="ratingOutput"></div>
</div>
これで完成です。
参考:このAngularJSの部分は、前のブログの記事のJSFiddleを使ったハローワールド!の事例と似ていますので、ご覧ください。
default.jsは、Part 1とほぼかわりません。違うところは、ボタンとinputフィールドにイベントハンドラーを登録するところと、イベントハンドラーの関数そのものが必要なくなります。
default.jsのソースコードは次のとおりです:
(function () {
"use strict";
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: このアプリケーションは新しく起動しました。ここでアプリケーションを
// 初期化します。
} else {
// TODO: このアプリケーションは中断状態から再度アクティブ化されました。
// ここでアプリケーションの状態を復元します。
}
args.setPromise(WinJS.UI.processAll().then(function completed() {
// レーティングコントロールのDIVタグのエレメントを参照する
var ratingControlDiv = document.getElementById("ratingControlDiv");
// レーティングコントロールそのものを参照する
var ratingControl = ratingControlDiv.winControl;
// レーティングコントロール用のイベントハンドラーを登録する
ratingControl.addEventListener("change", ratingChanged, false);
}));
}
};
app.oncheckpoint = function (args) {
// TODO: このアプリケーションは中断しようとしています。ここで中断中に
// 維持する必要のある状態を保存します。中断中に自動的に保存され、
// 復元される WinJS.Application.sessionState オブジェクトを使用
// できます。アプリケーションを中断する前に
// 非同期操作を完了する必要がある場合は、
// args.setPromise() を呼び出してください。
};
function ratingChanged(eventInfo) {
var ratingOutput = document.getElementById("ratingOutput");
ratingOutput.innerText = eventInfo.detail.tentativeRating;
}
app.start();
})();
default.cssは、Part 1と全くかわりありません。
Windowsストアアプリ+AngularJSをもっと相性良くする
これで、AngularJSを使ってWindowsストアアプリが作れましたね。ただ、AngularJSとWinJSとの相性をよくするためには、さらに努力が必要になります。
それについて次回サンプルを作りますね。
では、ばりばりAngularJSで、Windowsストアアプリ作ってください!
Mahalo!