目的
サーバーサイドから返却するJsonでクライアントにアレ・コレさせたいけれど、その都度値の受け渡し方法を考えたり、JavaScriptをゴリゴリ書くのは骨が折れるので共通化してみました。クライアントにさせたい仕事をサーバーサイドで簡単に記述できるのがメリットです。最新のJavaScriptフレームワークとか使えばこういうのいらないのかもしれません。
概要
サーバーサイドから返却するJsonを以下の形式で出力し、命令記号によるswitchでクライアントが行う処理を切り替えます。
・key 1文字目: 命令記号(クライアント側の処理の分岐に使用)
・key 2文字目以降: セレクタ(処理対象の選択)
・value: 処理対象に設定する値
Json例)##Issues_Ver: "3"
上記は、「#」が命令記号、「#Issues_Ver」がセレクタ、「3」が値です。
id="Issues_Ver"のvalueに3をセットせよという命令です。
実装例
クライアントサイドの処理
Transport.js
function request(requestUrl, methodType, data) {
return $.ajax({
url: requestUrl,
type: methodType,
cache: false,
data: data,
dataType: 'json'
})
.done(function (json, textStatus, jqXHR) {
if (json) {
// サーバーサイドから返却されたJsonを列挙
$.each(json, function (key) {
apply(key, this, data);
});
}
return true;
});
function apply(key, value, data) {
// keyの1文字目に含まれる命令記号を取得
var selector = key.substring(1, key.length);
// 処理対象のセレクタを選択
var $control = $(selector);
// Jsonに含まれる命令記号に基づき処理を分岐
switch (key.substring(0, 1)) {
case ' ': // htmlの書き換え命令
$control.html(value);
break;
case '>': // メッセージ領域への出力命令
setMessage(value);
break;
case '@': // 他のUrlへの遷移命令
location.href = value;
break;
case '_': // クライアントのデータ書き換え命令
data[$control.attr('id')] = value;
break;
case '+': // 要素の末尾に要素を追加する命令
$control.append(value);
break;
case '^': // 先頭に要素を追加する命令
$control.prepend(value);
break;
case '-': // 要素を削除する命令
$control.remove();
break;
case '.': // フォーカスをセットする命令
$control.focus();
break;
case '#': // 要素の値をセットする命令
setValue($control, value);
break;
case '$': // クライアント上のデータを書き換える命令
data[$control.attr('id')] = value;
setValue($control, value);
break;
case '%': // クライアント上のデータを消去する命令
clearFormData(selector, data);
break;
case ')': // clickなどイベントをキックする命令
$control.trigger(value);
break;
case '!': // 要素の内容を消去する命令
$control.empty();
break;
}
// メッセージ領域への出力
function setMessage(value) {
var $control = $('.message-dialog:visible');
if ($control.length == 0) {
$('#Message').html(value);
} else {
$control.html(value);
}
}
// 要素の値をセットする
function setValue($control, value) {
switch ($control.prop('type')) {
case 'checkbox':
$control.prop('checked', value);
break;
case 'radio':
$control.val([value]);
break;
default:
switch ($control.prop('tagName')) {
case 'SPAN':
$control.html(value);
default:
$control.val('' + value + '');
break;
}
}
}
}
}
サーバーサイドの処理(c# ASP.NET MVCの例)
命令記号の部分は定数などを割り当てておくと分かりやすいコードになります。
Newtonsoft.JsonはNuGetで取得しています。
response.cs
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Implem.Pleasanter.Libraries.Responses
{
public class IssueModel
{
// 更新処理を行った後にクライアントのバージョンテキストボックスの内容更新と
// メッセージ領域へのメッセージ出力を命令します。
public string Update()
{
// 更新処理を記述。
// レスポンス処理。
return JsonConvert.SerializeObject(new Dictionary<string, string>
{
{ "#" + "#Issues_Ver", "3" },
{ ">", Title + "の更新が完了しました。" }
});
}
}
}
動作イメージ
更新ボタン押下後にバージョンの数字が変更され、更新メッセージが表示されます。
ご参考
下記プロジェクトで使用しています。ほかにも実装例などがありましたら情報交換お願いします。
https://github.com/Implem/Implem.CodeDefiner