アーカイブ

Archive for 2012年6月

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の追加

astah thinkのショートカットキー

セミナーに参加した場合は、後で見直すためにマインドマップで話を自分なりにまとめることが多いです。Windowsでマインドマップを作成する場合は、チェンジビジョンのastah thinkを使っているます。

いつも使っているノートPC(thinkpad x210)であれば特に問題はないのですが、今回Windows8タブレット用に購入したbluetoothキーボード(RKB-2000BT3)にはInsキーがないのです。これまで子トピックを作る場合はInsキーで追加してきたので、あれ?これはキーボードレイアウトを変えなきゃダメか?なんて妄想なんかをしてしまいました。

何のことはありません。astah thinkのキーボードショートカットを見るとしっかりと子トピックの追加ショートカットがあるじゃないですか。すっごい今更ですね。いやーよかった。よかった。

マインドマップのショートカットキー http://astah.change-vision.com/ja/tutorial/mm-shortcut-key.html

カテゴリー:雑記

OS入れ替えたらインストールするリスト 2012年版

以前こんなエントリーを書いたんだけれど、ここのところインストール作業が多かったので、アップデートしてみる。

こうやって整理してみると結構入れているよなー。これ以外にOA系のインストール(Officeやらアーカイバソフトやら、PDFリーダーやら)もあるわけだから、新しい環境をまっさらから作るとそりゃ大変なわけだ。Windows完全バックアップやAcronisなんかのツールが重宝するわけです。

しかし微妙なタイミングになっちゃったな。後数ヶ月すればWindows 8やVisual Studio2012がでるというのに。。。

分類 ソフト名 備考
一般 Microsoft Live Essentials 無料のウイルス対策ソフト
Windows Live メッセンジャー、ブログ編集
paint.net 画像編集ソフト
astah think マインドマップ作成
Google 日本語入力 Google製IME
Google Calendar Sync  Outlook⇔Googleカレンダーの同期
ZoomIt デスクトップの拡大
Air Display スマートフォンをサブディスプレイに
(Windows8で動かしたら上手く動かなかったな。。。)
仮想化 Virtual CloneDrive ISOファイルのマウント
evernote クラウドへのノート保存
Dropbox クラウドへのファイル保存
SkyDrive クラウドへのファイル保存
VMware Player 無料の仮想PC動作環境
vSpherePower CLI vSphereのPowreShellインターフェイス
Webブラウザー Chrome GoogleのWebブラウザー
FireFox Webブラウザー
iBBDemo3 iPhoneのWebブラウザーエミュレーター
開発 TeraPad テキストエディター
dotPeek .NETアセンブリリフレクションツール
linqPad LINQクエリのエディター、動作確認
WinMerge ファイルの差分、マージツール
Fiddler HTTPデバッカー
  Process Explorer 実行中プロセスの詳細確認
Process Monitor プロセスがアクセスしているリソースを確認
Oracle SQL Developer Oracleでの開発に
Oracle Developer Tools for Visual Studio Oracleでの開発に
OSqlEdit Oracleでの開発に
Android SDK Android の開発に
Mono for Android Android の開発に
Visual Studio Visual Studio 2010 SP1 これを入れないと他が入らない
Windows Phone SDK Windows Phone開発
Windows Azure Windows Azure開発
Resharper これを入れないと開発できない
Team Foundation Server Power Tools December 2011 TFSにつなぐならこれ
SvnBridge SubversionからTFSへ
patterns & practices – Enterprise Library アプリ基盤の基盤に
Ajax Control Toolkit ASP.NET AJAX
NetMassDownloader シンボルのダウンロード
Productivity Power Tools 
Visual Studio 2010の拡張

PowerCommands for Visual Studio 2010
Visual Studio 2010の拡張

tangible T4 Editor 2.0 plus modeling tools for VS2010
T4開発のサポート

カテゴリー:インフラ, メモ, 雑記, Windows タグ: ,

TFSのバックアップって何やっているの?ちょっと覗いてみよう。

なーんか、TFSのフルバックアップが失敗するなーということで調査してみました。

TFSのバックアップには、TFS PowerToolsのバックアップツール(http://msdn.microsoft.com/ja-jp/library/ms253070.aspx)を利用しています。バックアッププランの作成については、りばてぃさんの記事がまとまっています。

TFS Advent Calendar Day 10~TFS 2010のバックアップとリストア~

まずはログの確認

何はともあれログの確認です。バックアップログはここに出力されます。→ C:\ProgramData\Microsoft\Team Foundation\Server Configuration\Logs

ログを確認すると、結構順調にバックアップを行なっているようなんだけれど、BackupSet(バックアップのカタログ?)の更新をしようとして、XMLのカタログファイルを読み込む段階でエラーになっているようです。

[Error  @06:16:49.170] System.InvalidOperationException: XML ドキュメント (302906,36) でエラーが発生しました。 —> System.Xml.XmlException: ‘.’ (16 進数値 0x00) は無効な文字です。 行 302906、位置 36。

   … 略 …

   — 内部例外スタック トレースの終わり —
   場所 System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   場所 Microsoft.TeamFoundation.PowerTools.Admin.Helpers.BackupSetSerializer.Load(String path)
   場所 Microsoft.TeamFoundation.PowerTools.Admin.Helpers.BackupSetHelper.AddAndSaveBackupSet(String path, TfsBackupSet backupSet)
   場所 Microsoft.TeamFoundation.PowerTools.Admin.Apply.TakeFullBackup.Run()

TFSのバックアップって何やっているの?

TFSのフルバックアップがやっていることを簡単にまとめると、次の4つになります。

  1. バックアッププラン定義ファイルの読み込み
  2. バックアップセットの作成
  3. バックアップの実行
  4. バックアップカタログの更新

バックアッププラン定義ファイルの読み込み

バックアッププラン定義ファイルは、バックアッププラン作成時にこのあたりに作成されます。→ C:\ProgramData\Microsoft\Team Foundation\Server Configuration\ConfigPT.xml

ConfigPT.xmlには、バックアップ対象のデータベースの一覧やバックアップ頻度、通知メール設定、レポーティングサーバーのバックアップキーファイルの場所など、バックアッププランの設定がすべて記述されています。

バックアップセットの作成

ConfigPT.xmlのTfsConfiguration, TfsCollections, TfsWarehouse, Reporting, Sharepointセクションからバックアップ対象のDatabase情報を取得し、バックアップセットを作成します。

バックアップの実行

Microsoft.SqlServer.Management.Smo.Backupクラスを利用して、ConfigPTから読み込んだDatabaseを順次バックアップしていきます。

バックアップカタログの更新

レストア時に参照するバックアップカタログを更新します。バックアップカタログはこのあたりに作成されます。→ バックアップフォルダー\BackupSets.xml

結局なんで落ちたの?

どうも、BackupSets.xmlがぶっ壊れていたようです。BackupSets.xmlを覗いたら、確かにこんな感じでXMLがぶっ壊れていました。

<TfsBackupSet Id="20120127033004" Time="2012/01/27 03:30:04">
  <Databases>
    <BackupSetDatabase Name="StateService_a02fc1fdb80b4052b21b6f5b74932695" File="" Parent="" />

    … 略 …

    <BackupSetDatabase Name="WSS_Search_SVTFS" File="" Parent="" />
    <BackupSetDatabase Name="Se

XMLを無理やり意味のある形に修正するか、壊れちゃったものは仕方ないとBackupSets.xmlを思い切って削除(!!)してもう一度フルバックアップをしてみましょう。もちろんBackupSets.xmlを削除すると、データベースのバックアップがあったとしてもTFSのバックアップシステムからレストアすることはできないので注意してください。

どうしたら良いかな?

Webで検索するとカタログファイルがぶっ壊れてしまったためにバックアップが失敗したり、レストアが出来なかったりと言った事例が見て取れます。ちょっと残念なんですが、カタログファイルは別途バックアップしておいたほうがいいかもしれません。

あともう一つ、ReportingServerのキーファイルはバックアッププラン作成時に作成されます。もしバックアップファイルを直に消すことがあっても、この子は消さないように注意しましょう。まぁ別途キーファイルを出力してあげればいいんですけれどね。

ふぅ、焦った。

カテゴリー:インフラ タグ:

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の呼び出しです。

Windows 8 CP → RP

image

Windows 8 Release Previewが公開されました。とりあえずComsumer Preview空のアップグレードインストールです。インストールにあたりココらへんは確認しておきましょう。

Windows 8RP http://windows.microsoft.com/ja-JP/windows-8/release-preview

Windows 8RP FAQ http://windows.microsoft.com/ja-JP/windows-8/faq

ダウンロード

ダウンロードは、WebインストーラーとISOファイルの2種類から選択可能です。

僕はISOファイルをダウンロードしました。ISOファイルのダウンロードリンクのしたぐらいにプロダクトキーがあるのでメモっておきましょう。

Webインストーラーhttp://windows.microsoft.com/ja-JP/windows-8/download

ISO:http://windows.microsoft.com/ja-JP/windows-8/iso

image

セットアップ

セットアップを開始すると、まずWindowsに適用するか聞かれます。まぁしておいたほうがいいので、「オンラインで今すぐ更新プログラムをインストールする。」を選択して次へボタンをクリック。ライセンス条項も確認して承認する。

image  image

アップグレードインストールなので、引き継ぐ項目の選択画面が表示されますが、FAQの「以前のバージョンの Windows から Windows 8 Release Preview にアップグレードすることはできますか。」に書かれているとおりComsumer Previewからはデータを引き継げないらしいので、「何も引き継がない」しか表示されません。

image  image

アップグレード中です。まぁCPからのアップグレードの場合は、殆どクリーンインストールと変わらないですけれどね。

image

初期設定

PCのテーマ色やその他PCの初期設定を行います。とりあえず簡単設定で先へ

image  image

PCのユーザー作成

PCへのサインインはローカルユーザーか、Live IDで行います。ネットワークに接続でき無い場合は、ローカルユーザーで設定後、チャームからPCの設定からLiveIdにローカルユーザーをひもづけることができます。

image image

Proxy設定の場合は、デスクトップ版のIEでプロキシ設定を行った後、コマンドプロンプトからIEのプロキシ設定を使うように設定する必要があるみたいです。

>netsh
netsh>winhttp
netsh winhttp>import proxy source=ie

起動時中の画面

起動時中は今までのWindowsよりも更にシンプルになりました。スタート画面はCPとそう変わっていないですね。

imageimage

カテゴリー:インフラ, Windows タグ: