Archive

Posts Tagged ‘モバイル’

jQueryからASP.NETのWCF Serviceの呼び出し

2012年6月19日 1件のコメント

WebFormでJavascript主体なスマートフォン向けサイトを作ろう その4

前回まででクライアント側のView-ViewModelの部分を作成したので、今回はクライアントのModelとそのModelが呼び出すサーバー側のサービスを作成していきます。今回は、knockout出てこないですね。WCFとJavascriptのお話です。

Webサービスの仕様

今回作成するサービスは、クライアントから渡されたキーワードをもとに検索を行い、検索にヒットしたデータの一覧を返すこととします。

WCFサービスとして作成するので、まずはデータコントラクトを作成します。今回はユーザーIdとユーザー名の2つを持つ簡単なエンティティークラスのリストを返却することします。データコントラクトはこんな感じになります。

Imports System.Runtime.Serialization

Namespace Entity
    <DataContract()>
    Public Class Customer
        <DataMember()>Property ユーザーId As String
        <DataMember()>Property ユーザー名 As String
    End Class
End Namespace

Webサービスの作成

次にWebサービスを本体を作成します。Visual Studioの新しい項目の追加から、「AJAX 対応 WCFサービス」を作成します。名前は、「FindService.svc」としておきます。

image

ここでは、ダミーの検索結果を返すメソッドFindを定義します。今回は、JavascriptとJSON形式のメッセージでやり取りしたいので、OperationContractにWebInvoke属性を追加して、Request、ResponseともにJSONでデータ交換を行うように宣言します。

<OperationContract()>
<WebInvoke(BodyStyle:=WebMessageBodyStyle.WrappedRequest, RequestFormat:=WebMessageFormat.Json, ResponseFormat:=WebMessageFormat.Json)>
Public Function Find(keyword As String) As List(Of Customer)
    Return New List(Of Customer) From {
            New Customer With {.ユーザーId = "karuakun", .ユーザー名 = "かるあくん"},
            New Customer With {.ユーザーId = "karua", .ユーザー名 = "かるあ"},
            New Customer With {.ユーザーId = "karukan", .ユーザー名 = "偽物"}
        }
End Function

クライアント側モデルクラスの作成(Webサービスの呼び出し)

実際にモデルクラスを作る前に、サーバーとはJSON形式でデータをやりとりするので、Javascriptオブジェクトをシリアライズ・デシリアライズするユーティリティークラスをひとつ導入しておきましょう。Nuget Package Consoleで、JSON2.jsをプロジェクトにインストールします。

PM> Install-Package json2
Successfully installed 'json2 1.0.2'.
Successfully added 'json2 1.0.2' to MobileTest.

クライアント側のモデルクラスを~/Script/Service以下に作成します。スクリプトの名前は、「CustomerService.js」としておきましょう。ちなみに、ソリューションはこんな感じで構成されています。

image

WebInvoke属性でマークしたWCFサービスのメソッドをjavascriptから呼び出す場合は、「WCFサービスのパス/メソッド名」で呼び出せます。WCFのパラメーター(data)はWCFのインターフェイスにあわせてJSON.stringifyメソッドでJSON文字列に変換します。

var customerService = (function () {
    var self = this;
    this.Find = function ($, keyword, successAction) {
        var data = JSON.stringify({keyword: keyword});
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            url: "Service/CustomerService.svc/Find",
            data: data,
            success: successAction(response)
        });
    };
});

スクリプトをマスターページに追加

スクリプトを追加したら、忘れずにマスターページに追加します。jquery.mobileの前であればどこでもいいのですが、依存関係からしてServiceはViewModelの前に追加しておいたほうがいいでしょう。

<%@ Master Language="VB" AutoEventWireup="false" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title></title>
    <link type="text/css" rel="stylesheet" href="Content/jquery.mobile-1.1.0.min.css"/>
    <script type="text/javascript" src='<%= ResolveClientUrl("~/Scripts/jquery-1.7.2.min.js") %>'></script>
    <script type="text/javascript" src='<%= ResolveClientUrl("~/Scripts/knockout-2.1.0.js") %>'></script>
 <script type="text/javascript" src='<%= ResolveClientUrl("~/Scripts/json2.min.js") %>'></script> <script type="text/javascript" src='<%= ResolveClientUrl("~/Scripts/Service/CustomerService.js") %>'></script>     <script type="text/javascript" src='<%= ResolveClientUrl("~/Scripts/ViewModel/FindCustomerViewModel.js") %>'></script>
    <script type="text/javascript" src='<%= ResolveClientUrl("~/Scripts/jquery.mobile-1.1.0.min.js") %>'></script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>

とりあえず呼び出してみよう

ViewModelでは、作成したモデルクラスをインスタンス化して呼び出すだけです。前回作ったViewModelにモデルのFindメソッドを呼び出すコードを追加します。

(function ($) {
    var viewModel = new (function () {
        var local = this;
        var service = new customerService();
        this.keyword = ko.observable("");

        this.find = function () {
            service.Find($, this.keyword(),
                function (result) {
                    var data = result.d;
                    alert(data.length);
                });
        };
    })();

    $(document).on("pageinit", "#FindCustomerView", function (event) {
        ko.applyBindings(viewModel, document.getElementById("FindCustomerView"));
    });
})($);

WCFをJSON形式の返却にした場合、dプロパティーの下にDataContractの内容が入ってきます。Fiddlerで、どんな文字列がHTTPに乗っているのかを確認して見ましょう。

image image

今回の例では、WCFから返却されたリストの件数をalert関数で表示しています。aspxをデバック実行して、検索ボタンをクリックしてみましょう。サービスの結果件数(3件)が表示されたのが確認できます。

image

次回はViewModelの更新とViewのリスト表示です。

過去へのリンクはこちらから

  • その1 はじめに
  • その2 ソリューション作成とライブラリの追加(knockout,jQuery,jQueryMobile)
  • その3 Knockoutを利用したViewModelの追加

Knockoutを利用したViewModelの追加

2012年6月5日 2件のコメント

WebFormでJavascript主体なスマートフォン向けサイトを作ろう その3

なんか間があいちゃいましたね。UIができたので、今回は業務ロジックとUIをつなぐViewModelを作成していきます。

Viewの変更

まずは画面の項目とJavascriptのバインディングをしておきましょう。前回のHTMLをこんな風に書き換えます。

<%@ Page Title="" MasterPageFile="~/Site.Master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <div data-role="page" id="FindCustomerView">
        <header data-role="header" data-position="fixed">
            <h1>顧客検索</h1>
        </header>
        <div data-role="content">
            <input type="text" data-bind="value: keyword"/>
            <input type="button" value="検索"

data-bind=”click: find”

 />
        </div>
    </div>
</asp:Content>

今回は検索キーワードをViewModelのkeywordプロパティーに、検索ボタンクリック時のイベントをViewModelのfindメソッドに割り当てています。

バインディングの詳細については、knockoutのドキュメントを確認しましょう。日本語の情報を探している場合は、このあたりが参考になります。そのうちちょこちょこ触れるかもしれません。

→ knockout.js 入門-鬼畜編<http://www.slideshare.net/shibayan/knockout-11523371>

 

ViewModelの追加と参照

続いてViewModel側の追加です。とりあえずView=ページとして作って置くと管理が楽そうなので、FindCustomerViewのViewModelは/Scripts/ViewMode/FindCustomerViewModel.jsとして作成しておきます。

image

続いて、追加したViewModelのJSファイルをマスターページに追加しておいてあげます(jQuery Mobileの場合は、ランディングページ以外は基本headerタグは読み込まれないので、利用するスクリプトはすべてマスターページに定義しておきます)。なんとなくViewModelの定義はknockoutの後、jQueryMobileの前に定義しています。

<%@ Master AutoEventWireup="false" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title></title>
    <link type="text/css" rel="stylesheet" href="Content/jquery.mobile-1.1.0.min.css"/>
    <script type="text/javascript" src='<%= ResolveClientUrl("~/Scripts/jquery-1.7.2.min.js") %>'></script>
    <script type="text/javascript" src='<%= ResolveClientUrl("~/Scripts/knockout-2.1.0.js") %>'></script>
    <script type="text/javascript" src='<%= ResolveClientUrl("~/Scripts/ViewModel/FindCustomerViewModel.js") %>'></script>
    <script type="text/javascript" src='<%= ResolveClientUrl("~/Scripts/jquery.mobile-1.1.0.min.js") %>'></script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>

マスターページ自体は今のところ、変わったところはありませんね。

ViewModelの定義

続いてViewModelの定義を行います。ViewModelには、検索キーワードとバインドするkeywordプロパティーと、検索ボタンがクリックされた際に呼び出されるfind関数を定義します。

(function ($) {
    var viewModel = new (function () {
        var local = this;
        this.keyword = ko.observable("");
        this.find = function () {
            //ToDo:サービスを呼び出してビジネスロジックを実行する。
            alert(local.keyword());
        };
    })();

    $(document).on("pageinit", "#FindCustomerView", function (event) {
        ko.applyBindings(viewModel, document.getElementById("FindCustomerView"));
    });
})($);
ViewModelでプロパティーの値を参照する場合は、ゲッター経由(関数呼び出し)なので注意しましょう。同じく設定する場合もセッター経由になります。

実行してみよう

この状態で実行すると、こうなります。

image

実行されましたか?

次回はjavascriptのモデルからWCFの呼び出しです。

ASP.NET WebFormでjQueryMobileを利用すると、jQuery.Validationと相性が悪すぎる。

ASP.NET WebFormでjQuery Mobileのページを作っていて、ハマったのでメモを残しておきます。

runat=”server”なFormを作らない=コードビハインド作れない=Postback使えない

いきなりWebFormを否定しています。jQuery Validationはformに対して設定するわけだけれど、MasterPageなんかでContentPlaceHolderをrunat=”server”なFormで囲われていると、ページごとにValidationが設定できなくて困っちゃうんですよね。

まずMasterPaceからformを消してしまいます。この時点で、コードビハインドが使えなくなるので、サーバーコントロールはもとより、PostBackやViewStateといったWebFormのプログラミングモデルはほとんど使えなくなります。実際スクリプトやCSSの参照にMasterPageを使いたいだけで、それがなかったらクライアント側はASPXでなくHTMLでもいいんですよね。サーバー側コードを動かす場合はすべてJavascript経由でWebサービスに頼ることになります。

<body>
<!-- <form runat="server" id="form1"> –>
<div>
<asp:ContentPlaceHolder ID="Contents" runat="server">
</asp:ContentPlaceHolder>
</div>
<!-- </form> –>
</body>
 
 

Formはdata-role=”page”の下に、データバインドはuniqueNameを追加する。

jQUeryValidationを動作させるにはform要素が必要になるんだけれど、jQueryMobileのページ遷移の特性上、data-role=”page”以下に配置された要素でないと、2ページ目以降は無視されてしまいます。なので、コンテンツページ側では、data-role=”page”以下に何もしないValidationのためのダミーFormを追加します。input要素にはclassにjQuery Validationの検証属性を設定します。

ここで注意したい点として、knockoutを併用する場合はデータバインド時にuniqueNameバインディングを追加してあげる事です。jQuery Validationは対象要素のidを必要とするので、このバインディングがないとエラーの表示時に混乱してしまうようです。

(あっ、、、あれ???uniqueNameバインディングは、複数ページに渡ってユニークな名前にしてくれるのかな???すべての検証が必要なコントロールに名前を付けなきゃいけないんだとしたら嫌だな。)

<asp:Content ID="Content1" ContentPlaceHolderID="Contents" runat="server">
<div data-role="page" id="FindCustomerView">
<form action="" id="FindCustomerViewForm">
<header data-role="header" data-position="fixed">
<h1>検証のテスト</h1>
</header>
<div data-role="content">
<div><label>名前</label>
<input type="text" class="required"
data-bind="text: name, uniqueName: true"/></div>
<div><label>メールアドレス</label>
<input type="email" class="required email"
data-bind="text: email, uniqueName: true"/></div>
<div><label>年齢</label>
<input type="number" class="number"
data-bind="text: age, uniqueName: true"/></div>
<input type="button" value="確定"/>
</div>
</form>
</div>
</asp:Content>

Javascript側では、viewModelを適応させるついでに、pageinitのタイミングで先程追加したFormに対してValidationを追加してあげます。
(function ($) {
karua.viewModel.topViewModel = function () {
this.name = ko.observable("");
this.email = ko.observable("");
this.age = ko.observable(0);
this.find = function () {
};
};
var viewModel;
$(document).on("pageinit", "#FindCustomerView", function (e) {
viewModel = new karua.viewModel.topViewModel();
ko.applyBindings(viewModel, document.getElementById("FindCustomerView"));
$("#FindCustomerViewForm").validate({ onsubmit: false });
});
})($);

そもそも

まぁモバイルでの値検証を、単純にデスクトップを想定した場合と同じUXでやっていいのか?という議論はまずあるだろうけれどね。

ソリューション作成とライブラリの追加(knockout,jQuery,jQueryMobile)

2012年5月21日 3件のコメント

WebFormでJavascript主体なスマートフォン向けサイトを作ろう その2

と言うことで、まずはWebフォームのプロジェクトを作って、もろもろのプラグインたちを参照するマスターページを作りましょう。

プロジェクトの作成

まずは新規プロジェクトで、空のWebアプリケーションを作成します。名前はMobileTestとかにしておきましょうか。

image

必要なスクリプトの追加

次にjQueryやjQuery Mobile、Knockoutといったスクリプトたちをダウンロードして追加していきます。

Visual StudioのPackage Manager Consoleを開いてNugetからプロジェクトに追加します。

PM> install-package jquery
PM> install-package jquery.mobile
PM> install-package knockoutjs

マスターページの追加

jQuery Mobileでは、ユーザーが最初に開いたエントリーページ以降は、ページ遷移時にヘッダータグを読み飛ばすので、すべてのページには同じヘッダータグを記述して、スクリプトやCSSの読み込み漏れが起こらないようにします。

ASP.NET WebFormでは、マスターページを利用すると簡単です。

image

先程追加した、Javascriptファイルたちをマスターページに追加していきます。

<%@ Master Language="VB" AutoEventWireup="false" CodeBehind="Site.master.vb" Inherits="MobileTest.Site" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title></title>    <meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1"/>
    <link type="text/css" rel="stylesheet" href="~/Content/jquery.mobile-1.1.0.min.css"/>
    <script src='<%= ResolveClientUrl("~/Scripts/jquery-1.7.2.min.js") %>' type="text/javascript" ></script>
    <script src='<%= ResolveClientUrl("~/Scripts/knockout-2.1.0.js") %>' type="text/javascript" ></script>
    <script src='<%= ResolveClientUrl("~/Scripts/jquery.mobile-1.1.0.min.js") %>' type="text/javascript" ></script> 
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>

トップページの追加

次に最初に表示する画面(Top.aspx)を追加します。最初に表示する画面は、必要なスクリプト等を読み込んだSite.Masterをマスターページとして利用します。

image image

<%@ Page Title="" AutoEventWireup="false" MasterPageFile="~/Site.Master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <div data-role="page" id="FindCustomerView">
        <header data-role="header" data-position="fixed">
            <h1>顧客検索</h1>
        </header>
        <div data-role="content">
            <input type="text"/>
            <input type="button" value="検索" />
        </div>
    </div>
</asp:Content>

画面の表示

とりあえずVisual Studioのデバック実行で画面を表示してみましょう。

こんなふうに表示されましたか?

image

現在のソリューションの状況

こんな感じです。

image

次回はViewModelの追加です。

jQuery Mobileでトースト通知

jQueryMobileでシステムからのメッセージを表示する場合に、ダイアログ表示ではなくトースト通知っぽい表示をしたかったのでこんな関数を作ります。

karua.ui.message.showToast = function (message) {
var box = $("<div class='ui-loader ui-overlay-shadow ui-body-a ui-corner-all'>"
+ message + "</div>")
.css({
"padding": "7px 25px 7px 25px",
"display": "block",
"opacity": 0.8
})
.appendTo($.mobile.pageContainer);

var left = Math.floor(($(window).width() – box.width()) / 2);
box.css({
"top": $(window).scrollTop() + 100,
"left": left
})
.delay(1500)
.fadeOut(400, function () {
$(this).remove();
});
};

ViewModel側でメッセージを表示するの良くない。とかはとりあえずおいておいて、こんなふうに呼び出せば。

karua.viewModel.topViewModel = function () {
this.keyword = ko.observable("");
this.find = function () {
if (this.keyword() == "") {
karua.ui.message.showToast("検索キーワードが空だよ");
return;
}
};
};

こんな感じで表示される。うーん。微妙に右によってますね。。。

image

「jQuery Mobile toast」「jQuery Mobile トースト」 とかだとあんまり引っかからなかったけれど、「jQuery Mobile メッセージ」「jQuery Mobile ポップアップ」とかだと同じ事やっている人結構引っかかるのね。トースト通知ってあんまりメジャーな言い方じゃないのかな。

プラグインになってないのかなーと思ったら、nugetにjquery.mobile.messageという名前で、トースト通知を行うjQueryのプラグインがすでに登録されてた。はぅー。

https://packages.nuget.org/packages/jQuery.Mobile.Message/1.6.9

WebFormでJavascript主体なスマートフォン向けサイトを作ろう

2012年5月8日 2件のコメント

いまさらですが、スマートフォン向けのWebサイトが旬ですね。

スマートフォン向けのWebサイトは、今までのモバイルサイトと違い、HTML5に対応した記述で行えることもあって、WebFormよりもHTMLを自由に記述できるASP.NET MVCのほうが相性が良いです。

逆にWebFormだとスマートフォン向けサイトを作る上でこのあたりが障害になります。

  • マスターページなどを利用すると、HTMLの要素のIDをフレームワークがつけてしまう
  • 一部のコントロールは、インラインスタイルをつけてしまうのでCSSが適用しにくい
  • 一部のリスト系のコントロールは、構造がテーブルになってしまうものがあって使いにくい

特にフレームワークにjQuery Mobileを利用する場合は、jQuery Mobileの制約ともろにぶつかってしまってやりにくいです。

  • AJAXでのページ遷移を利用する場合は、すべてのページで要素のIDを固有にしたほうが良い
  • JavascriptやCSSはすべてのページで同じ物を読み込むようにする

じゃぁ、サーバーコントロール使わなきゃいいんじゃね?ということでこんな感じでスマートフォン向けサイトを作って見る。

  • Formを用意しない
  • サーバーコントロールを使わない(マスターページ除く)
  • ASPXのコードビハインドを使わない
  • 認証はASP.NETのものを使う
  • 通信はすべてJavascriptとWCFを使った非同期通信
  • モバイル用のフレームワークはjQueryMobileを使う
  • HTMLとJavascriptのバインディングにはKnockoutを使う

WebFormの特徴を完全に無視していますね。もうMVCでいいんじゃね?という声が聞こえてきそうですが。とりあえずこれでやります。

WindowsPhoneアプリをPhoneGapでつくろう

PhoneGap1.2ってWindowsPhoneに正式対応してたんですね。いつのまにやらGitHubからApatchSoftwareFoundationに組み込まれてるし。ちょっと離れるとびっくりすることがたくさんです。

まずはインストールしてみましょう。

PhoneGapってなに

PhoneGapを使うと、JavascriptとHTMLでWindowsPhone、Android、iOS用のハイブリットアプリ(HTMLアプリをブラウザーコントロール経由でネイティブアプリとして使う)を作成することができます。

Mono for AndroidなんかだとコアロジックはC#で書くけれど、プレゼンテーションレイヤーは各環境に応じて実装してねいうスタンスだったのに対し、各スマートフォン環境ではWebの標準技術であるHTML5+Javascriptを標準でサポートしているんだから、Webブラウザーコントロールを使ってパッケージに組み込んだローカルHTMLと+ネイティブ機能の拡張でどの環境でも動くようにしてしまおうという方針。

WindowsPhone 7.1

前述のとおり、他の環境への移植を考えると標準技術であるHTML5+jQueryMobileで実装してしておいたほうがいいでしょう。となると、ほとんどHTML5を理解出来ないIE8のWindowsPhone7だと無理があって、必然的にIE9以上が採用されているWindowsPhoneは7.1(Mango)以降が対象になります。

インストール

Windows Phone SDK 7.1のインストール

PhoneGapを利用する場合、各スマートフォンのSDKが必要になるのでWindowsPhone用アプリの開発に必要なWindows Phone SDK 7.1をダウンロードしてインストールしましょう。こいつを入れると無料のVisual Studioも一緒に入るのでお手軽です。

PhoneGap1.2のインストール

しばらく前までは、最新版はGitHubのWindowsPhone用のリポジトリからダウンロードできていたんだけれど、ASFに移動してからはどこに最新ソースがあるかいまいちわかりません。とりあえず最新版であるPhoneGap1.2はPhoneGapのホームページか、日本のファンサイトであるPhoneGapFunからダウンロードできます。

追記 GitHub上はココにあるようです。https://github.com/callback/callback-windows-phone

ダウンロードした「callback-phonegap-1.2.0-0」なZIPファイルを解凍すると、WindowsPhoneディレクトリーにPhoneGapのWindowsPhone用のフレームワークや、サンプルアプリ、Visual Studioのテンプレートが格納されています。Visual Studioで開発を行うには、「GapAppStarter.zip」をVisual Studioのユーザー別テンプレートフォルダーにコピーします。

Windows 7, Vistaの場合のコピー先

%UserProfile%\Documents\Visual Studio 2010\Templates\ProjectTemplate

プロジェクトの作成

Visual Studioの新しいプロジェクトダイアログでC#のプロジェクト一覧に、「GapAppStarter」というプロジェクトテンプレートが表示されます。下記はPhoneGapでフィルターした結果。

image

プロジェクトを作成すると、次のようなすぐに実行可能なPhoneGapのロジェクトが作成されます。

image

実行するとこんな感じの画面が起動します。エミュレーターの起動や動作が早いっていいですね。Andoriodエミュレーターはなんであんなに起動や動作が重いんだろう。。。(このエミュレーターの動作だけでもVisual Studioを採用する意味があるきがする。)

image

jQueryMobileの組み込み

せっかくのハイブリッドあぷりなのだから、複数のデバイスで動かせるようにHTMLを構成したいということで、PhoneGapでアプリを作成する場合はUI系のフレームワークを導入します。まぁいまだったらjQueryMobileを選ぶのが無難ですよね。Visual Studioを利用しているので、Package Manager Consoleから、jQuery.Mobileをインストールしましょう。もちろんCDNのスクリプトを参照してもいいけれど、出来ればオフラインで使いたいので。。。

PM> Install-Package jQuery.Mobile

ただこのままだとCSSとスクリプトがプロジェクトのルートフォルダーに展開されてしまうので、PhoneGapのしきたり(?)に則ってwwwフォルダー以下に移動させてあげましょう。(Update-Package時には結局再度コピーし直さないと行けないけれど、NuGetでインストールしたモジュールの配置先の変更を設定とかできないもんかな)

PhoneGapで最初に読み込まれるHTMLはwww/index.htmlなので、インストールしたjQueryMobileを読み込みます。

<head>   <title>WindowsPhone7.5 PhoneGapSample</title>   <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />   <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>   <link rel="stylesheet" href="Content/jquery.mobile-1.0rc2.min.css" />   <script type="text/javascript" src="Scripts/jquery-1.6.4.min.js"></script>   <script type="text/javascript" src="Scripts/jquery.mobile-1.0rc2.min.js"></script>
</head>

あとはjQueryMobileなので、こんなHTMLをbodyに書いてあげれば

<body>
<section data-role="page">   <header data-role="header"><h1>PhoneGapSample</h1></header>   <section data-role="content">     最近読んだ本     <ol data-role="listview">       <li>スティーブ・ジョブスⅠ、Ⅱ</li>       <li>GATE7 2巻</li>       <li>リアル9巻</li>       <li>魔法科高校の劣等生3巻</li>     </ol>   </section>   <footer data-role="footer">wordpress.karuakun.com</footer>
</section>
</body>

こんなかんじで表示されます。見た目はブラウザーアプリなんですが、WindowsPhoneにちゃんとインストールされてオフラインでも動きます。

image

あれ?PhoneGapのライブラリーでエラー?

って、ここまでは良かったんだけれど、PhoneGapのJS側でエラーが出るみたいで、phonegap-1.2.0.jsをリンクするとページが真っ白になっちゃう。どうもJavascript側でエラーになっているようなんだけれど、Visual Studio側でエラーが起きても止まってくれない。。。

WindowsPone版のPhoneGapって、実際はWebBrowserコントロールのラッパーになっているので、こいつがJavascriptのエラーをちゃんとVisual Studioに通知してくれればいいんだけれど。。。うーん。悩んでもわからなかったので今日はここで終わり。