アーカイブ

Archive for the ‘モバイル’ Category

ASP.NET 4 WebFormでモバイルサイトを作成する場合のスクリプト結合

これはOne ASP.NET Advent Calendar 2012の12/17日分の記事となります。前回の記事はnobuhisaさんの「知っている人は知っている、知らない人は知らない『NDjango』」です。次回の記事はnakamura_toさんです。

。。。やべっす。書くネタが無いです。ASP.NETといっても、いろいろありますが基本WebFormしか触っていないので、ちょうど都合よく発生した、お仕事で困ったことで逃げるとします。

スクリプトがいっぱい

少し前ですがWebFormとjQueryMobile、knockoutを基盤に使ったシステムの開発方針を決めたことがあります。もともと単純な機能しか利用しないし画面もそう多くないのででさらっと作れればいいよーという話だったので、メンテナンス性を考え、ページはViewModel毎に1つのJavascriptファイルと、ViewModelが利用するサービスクラスが名前空間毎にファイルを分けて作成することにしました。

開発が終盤になり、なんとなくソリューションを覗いてみたら、画面や機能はどんどん追加され、Javascriptだけでも40以上がマスターページに登録されていました。

スクリプトのロードを早くしたい

ASP.NETでjQueryMobileなページを作成する場合、どのページからランディングされても動くように、マスターページ側でそのサイトで利用する全てのスクリプトをロードさせます。このため、初めてのそのサイトにアクセスの場合は、数十のスクリプトがロードされることになり、場合によってはそれなりにロード時間がかかります。

Fiddlerでネットワーク帯域のエミュレートをしながらダウンロードを調査してみました。Fiddlerでのネットワーク帯域の制限方法はココが参考になります(→Android開発で3G回線速度を再現する)。近頃のモバイルネットワークは高速ですが、今回は下りが大体512kbpsぐらいに制限して調査してみます。

image image

タイムラインは下のほうが切れてしまっていますが、ページ全体で758KBの読み込みで、2.8秒の時間がかかっています。

ASP.NET 4 WebFormでの解決案

ASP.NET 4.5では、System.Web.Optimization名前空間を使った便利な仕組みがあるようなのですが、ASP.NET 4な環境では使えません。チャックさんのJavaScript / CSS ファイルの自動縮小・結合処理: ASP.NET MVC 4 新機能シリーズがわかりやすいです。

ASP.NETでは古くからのScriptMangerコントロールにも、スクリプトの結合機能(クライアント スクリプトを複合スクリプトに結合)があります。今回はScriptManagerのスクリプト結合機能を利用してjQueryやknockout, jQueryMobileのスクリプトを結合することでスクリプトのロードが早くなるかを検証します。

ScriptManagerのCompositeScript機能を利用したスクリプトの結合

まずはマスターページを開いて、ScriptManagerを追加します。

今回、ASP.NET AJAX関連JavaScriptは読み込む必要は無いのでAjaxFrameworkModeをDisabledに変更しています(あっ、ScriptManagerはrunat=”server”なformの中に置きましょうね。ココの記事ではformを消してしまいましたが、無いと上手く動いてくれません)。

<asp:ScriptManager runat="server" AjaxFrameworkMode="Disabled">
<CompositeScript>
    <Scripts>
        <asp:ScriptReference Path="~/Scripts/json2.min.js"/>
        <asp:ScriptReference Path="~/Scripts/jquery-1.7.2.min.js"/>
        <asp:ScriptReference Path="~/Scripts/jquery.validate.min.js"/>
        <asp:ScriptReference Path="~/Scripts/knockout-2.1.0.js"/>

        <asp:ScriptReference Path="~/Scripts/jquery.mobile-1.1.0.min.js"/>
        <asp:ScriptReference Path="~/Scripts/jquery.mobile.datebox.min.js"/>
        <asp:ScriptReference Path="~/Scripts/jquery.mobile.datebox.i8n.jp.js"/>
    </Scripts>
</CompositeScript>
</asp:ScriptManager>

さて実行するとどうなるかな?。。。。。。ありゃ、Javascriptのエラーが出ちゃいました。どうもjson2が上手く読み込めていない様子なので、外に出してあげます。

image

マスターページのコードはこうなりました。

<%@ Master Language="VB" AutoEventWireup="false" CodeBehind="Site1.master.vb" Inherits="WebApplication6.Site1" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=5.0,user-scalable=yes"/>
    <link href='~/Content/jquery.mobile-1.1.0.min.css' rel="stylesheet" type="text/css"/>
    <script type="text/javascript" src='<%= ResolveClientUrl("~/Scripts/json2.min.js") %>'></script>
    <asp:ContentPlaceHolder ID="Head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form runat="server">
    <asp:ScriptManager runat="server" AjaxFrameworkMode="Disabled">
        <CompositeScript>
            <Scripts>
                <asp:ScriptReference Path="~/Scripts/jquery-1.7.2.min.js"/>
                <asp:ScriptReference Path="~/Scripts/knockout-2.1.0.js"/>

                ... 略 ...

                <asp:ScriptReference Path="~/Scripts/jquery.mobile-1.1.0.min.js"/>
                <asp:ScriptReference Path="~/Scripts/jquery.mobile.datebox.min.js"/>
                <asp:ScriptReference Path="~/Scripts/jquery.mobile.datebox.i8n.jp.js"/>
            </Scripts>
        </CompositeScript>
    </asp:ScriptManager>
    </form>                
    
    <asp:ContentPlaceHolder ID="Contents" runat="server">
    </asp:ContentPlaceHolder>
</body>
</html>

どかなー

とりあえず適当なページを作って実行すると、問題なく表示されましたね。

image

コンテンツのロード状況を見ると、ページ全体で239KBの読み込みで1.9秒の時間がかかっています。ページのサイズとしては500KBの軽量化、ページのロード時間としては1秒ぐらい早くなっています。ScriptManagerのComposit機能では、スクリプト自体の圧縮を行わないのでこんなものでしょうかね。

imageimage

Ajax Minifierでビルド時にスクリプトファイルを圧縮してあげると、スクリプト自体のサイズが小さくなるのでもう少し早くなるかもしれませんね。

広告
カテゴリー:ASP.NET, インフラ, モバイル タグ:

GL04Pの更新

イーモバイルのGL04Pというモバイルルーターを使っています。以前使っていたGP02に比べ大きくはなりましたが、LTEに対応してかつバッテリーの持ちも良いので、常に持ち歩いています。ただ、Windows7やAndroid、iOSだと特に問題ないのですが、Windows 8だと頻繁に「制限付きアクセス」と表示されてしまいます。

今日、GL04Pを再起動したらこんなメッセージが表示されていました。

image

管理画面のアップデートにはこんなメッセージ

image

おっ、Windows 8対応!!、更にNAS対応!!これは期待。

メモ http://luispc.com/archives/1837

カテゴリー:インフラ, モバイル

Knockoutで取得したデータをjQueryMobileに反映する。

WebFormでJavascript主体なスマートフォン向けサイトを作ろう その5 #タイトルの付け方を変えました。

前回までで、サーバー側のWebServiceをJavascriptから呼び出し、結果を取得するところまで作成しました。

次に結果を画面に反映する部分を作成しましょう。

ViewModelの変更

前回取得したWebサービスの値をKnockout経由でView側に通知させます。

JQuery Mobileを直に利用している場合、DOMを変更したら各要素をrefleshしてあげないとスタイルが反映されないんだけれど、knockoutを利用した場合は特に何もせずに反映されるんですよね。ただ、サンプルなんかを見るとrefleshを発行しているものもあり。必要かどうかよくわかりません(汗。見た目問題なく動いているんですけれどね。

var viewModel = new (function () {
var local = this;
var service = new customerService();

this.keyword = ko.observable("");
this.検索結果 = ko.observableArray([]);
this.件数 = ko.computed(function () {
return local.検索結果().length;
});

this.find = function () {
local.検索結果.removeAll();
service.Find($, this.keyword(),
function (result) {
var data = result.d;
ko.utils.arrayPushAll(local.検索結果, data);
// $("#リストのID").listview('reflesh');
});
};
})();

配列と計算用のプロパティー

一覧表示用のデータ等は、通知に対応した配列(ko.observableArray)をプロパティーとして用意します。

件数などで、特定のプロパティーの値をそのまま利用できるようなプロパティーは、計算に対応したプロパティー(ko.computed)として定義してあげるとプロパティーの更新漏れなんかがなくて良いです。今回は検索結果を格納した配列の要素数がそのまま検索結果件数なので、検索結果().lengthを返却しています。

検索結果の追加

検索した結果は、ko.observableArrayなプロパティーに1件づつpushしていっても良いのですが、ko.utilsに配列をまるごとpushするユーティリティー(arrayPushAll)が用意されているので、こいつを利用しましょう。

observableArrayに追加する要素は、本来observableなプロパティーを持つクラスを指定できますが、今回はリストに表示するだけで、かつ各要素に対する変更も受け取る必要が無いので、WCFから受け取ったデータ(result.d)をそのまま配列に追加しています。

Viewの変更

以前作ったViewに結果リストを表示するためのリストと、結果件数を表示するためのラベルを追加します。

<%@ 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" />
<p>検索結果件数:<span data-bind="text: 件数"></span></p>
<ul data-role="listview" data-bind="foreach: 検索結果">
<li><a data-bind="attr: { href: 'Detail.aspx?jyu=' + ユーザーId }">
<h4><span data-bind="text: ユーザー名"></span></h4>
<p>(<span data-bind="text: ユーザーId"></span>)</p>
</a></li>
</ul>
</div>
</div>
</asp:Content>
listviewと配列のバインド
jQuery Mobileでリストを表示したい場合は、data-role属性でlistviewを指定します。
また、data-bind属性で、foreach: observableArrayなプロパティーを指定すると、配列をリストにバインドできます。
配列バインドのテンプレート
knockoutでは、foreachでバインディングした要素の配下を配列要素数分繰り返します。
検索結果という配列に3個の要素があったなら、この部分が3回繰り返されることになります。
<li><a data-bind="attr: { href: 'Detail.aspx?jyu=' + ユーザーId }">
<h4><span data-bind="text: ユーザー名"></span></h4>
<p>(<span data-bind="text: ユーザーId"></span>)</p>
</a></li>
この部分に関してはそれほど特筆する点はありませんね。実行してみると、liの部分がテンプレートで記述した要素通りに、3つ追加されているのを確認できます。
image
 
実行するとこんなかんじに表示されます。さて、一応表示までできましたね。

この画面から遷移する予定のDetail.aspx側(更新)も気が向いたら書きます。

image
 

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

  • その1 はじめに
  • その2 ソリューション作成とライブラリの追加(knockout,jQuery,jQueryMobile)
  • その3 Knockoutを利用したViewModelの追加
  • その4 jQueryからASP.NETのWCF Serviceの呼び出し

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の追加です。