読者です 読者をやめる 読者になる 読者になる

pblog

pplog.net を作っている @ppworks こと越川直人(Koshikawa Naoto)のブログ

UserPrefの代わりに永続化データを設定したりする画面を作ってみる

javascript OpenSocial mixiアプリ

前回はjOpenSocialを使ったサンプルだったので、今回はopensocial-jqueryを使ってみます。といいつつ、せっかくなのでjOpenSocialとopensocial-jqueryとを比べながら色々試してみようと思います。(飽きるまでたまに書くかも)

mixiアプリでは今のところUserPrefが使えないので、UserPrefの代わりに永続化データを設定したりする画面に使うことが多いかと思います。そこで、opensocial-jqueryやら、jOpenSocialやらを用いてそういった画面を作ってみます。

まずは各ライブラリのドキュメント

viewerがownerであるか確認する

例えば、あらかじめGadget XMLに以下のような設定用フォームがあるとします。

f:id:naoto5959:20090508214749p:image

今回はとても質素なフォームですが、jQueryを使えば色々なフォームの要素を楽に扱えると思います。

<div id="setting" style="display:none">
<fieldset>
  <legend>UserPrefっぽいフォーム</legend>
  <form>
    <dl>
    <dt><label for="user_setting1">user_setting1</label></dt>
    <dd><input type="text" id="user_setting1" name="user_setting1" /></dd>
    <dt><label for="user_setting2">user_setting2</label></dt>
    <dd><input type="text" id="user_setting2" name="user_setting2" /></dd>
    </dl>
    <input type="submit" value="設定" /><input type="reset" value="リセット" />
  </form>
</fieldset>
</div>

viewerがownerである場合、このフォームを表示する処理を記述してみましょう。どちらもViewerの情報を取得して、ownerかどうかをチェックする処理となります。

opensocial-jquery
$.getData('/people/@viewer/@self', {},
  function(people) {
    var person = people[0];  
    if (person.isOwner) {
      $('#setting').show();
    }
  }
);
jOpenSocial
$.opensocial.person("VIEWER",
  function(data) {
    if (data.isOwner()) {
      $('#setting').show();
  }
});

UserPrefの代わりに作ったのに、これではタダの空フォームが表示されるだけです。せっかくなので永続化データを取得してみましょう。

とはいえ、永続化データをどんなデータにするかを考えていません。まずはデータの設計を行います。今回は、フォームの値が2つありますので2つのキーを定義してあげればよさそうです。inputのidと同様に以下のキーを定義します。

  • user_setting1
  • user_setting2

永続化データを取得その1

opensocial-jquery
$.getData('/appdata/@viewer/@self', {},
  function(data) {
    $.each(data, function(userId, data) {
      $('#user_setting1').val(data.user_setting1);
      $('#user_setting2').val(data.user_setting2);
    });
  }
);
jOpenSocial

jOpenSocialでは一度に複数のキーを取得出来ないようなので、2回に分ける必要があります。
というのは誤りで、trunkのjOpenSocialを使うと出来ました。以下のスクリプトは2回に分けた場合。

$.opensocial.data.get(
  "user_setting1",
  "owner",
  function(data) {
    $('#user_setting1').val(data);
  },
  false
);

$.opensocial.data.get(
  "user_setting2",
  "owner",
  function(data) {
    $('#user_setting2').val(data);
  },
  false
);

1回で取得するには以下のように行うことが出来ました。

$.opensocial.data.get(
  ["user_setting1", "user_setting2"],
  "owner",
  function(data) {
    $('#user_setting1').val(data.user_setting1);
    $('#user_setting2').val(data.user_setting2);
  },
  false
);

もしくは、

$.opensocial.data.get(
  "*",
  "owner",
  function(data) {
    $('#user_setting1').val(data.user_setting1);
    $('#user_setting2').val(data.user_setting2);
  },
  false
);

ちょっと嫌ですね。これは永続化データの定義を変えるといいかも知れません。例えば以下のキーを定義します。

trunkのjOpenSocialでは複数のキーを取得出来るようなので、参考としてキーを2つに分けない方法として以下のキーを定義します。

  • user_setting

そして、値には

{
  user_setting1: "user_setting1のvalue",
  user_setting2: "user_setting2のvalue"
}

こうすると、先ほどの取得処理は以下のように変更できます。

永続化データを取得その2

opensocial-jquery
$.getData('/appdata/@viewer/@self', {},
  function(data) {
    $.each(data, function(userId, data) {
      $('#user_setting1').val(data.user_setting.user_setting1);
      $('#user_setting2').val(data.user_setting.user_setting2);
    });
  }
);
jOpenSocial
$.opensocial.data.get(
  "user_setting",
  "owner",
  function(data) {
    if (!data) return;
    $('#user_setting1').val(data.user_setting1);
    $('#user_setting2').val(data.user_setting2);
  },
  false
);

partuzaではこんな感じで値が入っています。
f:id:naoto5959:20090508215227p:image

この辺りの永続化データの持たせ方は、好みが分かれそうなところです。
とりあえず以下の説明では、user_settingキーを定義して、各キーを持ったObjectを永続化させた例を示します。
さて、お気づきかと思いますが、どちらの例でもデータが取得できません。なぜなら永続化データを保存していないからです。それでは永続化データを保存してみましょう。

永続化データを保存

opensocial-jquery
$.postData('/appdata/@viewer/@self', {
  'user_setting': 
    {
      user_setting1: $('#user_setting1').val(),
      user_setting2: $('#user_setting2').val()
    },
  },
  function() {}
);
jOpenSocial
$.opensocial.data.set(
  "user_setting",
  {
    user_setting1: $('#user_setting1').val(),
    user_setting2: $('#user_setting2').val()
  },
  function() {}
);

これを[設定]ボタンをクリックした際に実行してあげれば、ちょっとしたユーザ設定の保存画面の完成です。

一旦まとめてみる

ここまでの処理をfunctionを使って、まとめるみると以下のようになります。ちょっと長いです。

opensocial-jquery
/**
 * opensocial-jqueryバージョン
 */
/**
 * jQueryprototype.jsのFunction.bind()と同様の処理を行う拡張
 */
jQuery.scope = function(target,func){ return function() { return func.apply(target,arguments);}};

var UserSettingSample = function() {
  var _isOwner = false;
  /**
   * isOwner
   * 現在のviewerがownerであるかどうかを示す
   */
  this.isOwner = function() {
    return _isOwner;
  };
  
  /**
   * initialize
   * 初回に実行するメソッド
   */
  this.initialize = function() {
    this.checkViewerIsOwner();
  };
  
  /**
   * 現在のviewerがownerであるかどうかを確認する
   */
  this.checkViewerIsOwner = function() {
    $.getData('/people/@viewer/@self', {}, $.scope(this, this.checkViewerIsOwner_Result));
  };
  
  this.checkViewerIsOwner_Result = function(people) {
    var person = people[0];  
    _isOwner = person.isOwner;
    if (this.isOwner()) {
      this.activateSetting();  
      this.fetchStoredData();
    }
  };
  
  /**
   * id:settingで囲まれたフォームを有効化する
   */
  this.activateSetting = function() {
    $("#setting").show();
    
    $("#setting input[type='submit']").bind("click", {that: this}, function(event) {
      event.preventDefault();
      event.data.that.putStoredData();
    });
  };
  
  /**
   * fetchStoredData
   * 永続化データを取得する
   */
  this.fetchStoredData = function() {
    $.getData('/appdata/@owner/@self', {}, $.scope(this, this.fetchStoredData_Result));
  };
  
  this.fetchStoredData_Result = function(data) {
    $.each(data, function(userId, data) {
      $('#user_setting1').val(data.user_setting.user_setting1);
      $('#user_setting2').val(data.user_setting.user_setting2);
    });
  };
  
  /**
   * putStoredData
   * 永続化データを保存する
   */
  this.putStoredData = function() {
    $.postData('/appdata/@viewer/@self', {
      'user_setting': {
        user_setting1: $('#user_setting1').val(),
        user_setting2: $('#user_setting2').val()
      }
    }, function() {});
  };
};
jOpenSocial
/**
 * jOpenSocialバージョン
 */
/**
 * jQueryprototype.jsのFunction.bind()と同様の処理を行う拡張
 */
jQuery.scope = function(target,func){ return function() { return func.apply(target,arguments);}};

var UserSettingSample = function() {
  var _isOwner = false;
  /**
   * isOwner
   * 現在のviewerがownerであるかどうかを示す
   */
  this.isOwner = function() {
    return _isOwner;
  };
  
  /**
   * initialize
   * 初回に実行するメソッド
   */
  this.initialize = function() {
    this.checkViewerIsOwner();
  };
  
  /**
   * 現在のviewerがownerであるかどうかを確認する
   */
  this.checkViewerIsOwner = function() {
    $.opensocial.person("VIEWER", $.scope(this, this.checkViewerIsOwner_Result));
  };
  
  this.checkViewerIsOwner_Result = function(data) {
    _isOwner = data.isOwner();
    if (this.isOwner()) {
      this.activateSetting();  
      this.fetchStoredData();
    }
  };
  
  /**
   * id:settingで囲まれたフォームを有効化する
   */
  this.activateSetting = function() {
    $("#setting").show();
    
    $("#setting input[type='submit']").bind("click", {that: this}, function(event) {
      event.preventDefault();
      event.data.that.putStoredData();
    });
  };
  
  /**
   * fetchStoredData
   * 永続化データを取得する
   */
  this.fetchStoredData = function() {
    $.opensocial.data.get(
      "user_setting",
      "owner",
      $.scope(this, this.fetchStoredData_Result),
      false
    );
  };
  
  this.fetchStoredData_Result = function(data) {
    console.info(data);
    if (!data) return;
    $('#user_setting1').val(data.user_setting1);
    $('#user_setting2').val(data.user_setting2);
  };
  
  /**
   * putStoredData
   * 永続化データを保存する
   */
  this.putStoredData = function() {
    
    $.opensocial.data.set(
      "user_setting",
      {
        user_setting1: $('#user_setting1').val(),
        user_setting2: $('#user_setting2').val()
      },
      $.scope(this, this.putStoredData_Result)
    );

  };
  
  this.putStoredData_Result = function(data) {
    
  };
  
};

いずれも

$(function() {
  var userSetting = UserSettingSample();
  userSetting.initialize();
}

というように実行すると先に示したような設定画面っぽい何かが表示されます。

submitボタンのハンドラについて

jOpenSocial、opensocial-jqueryではなくjQueryのお話なんですが、submitボタンのハンドラ設定の部分は他にもこんなやり方があります。

$.scopeを使う
$("#setting input[type='submit']").click($.scope(this, function(event) {
  event.preventDefault();
  this.putStoredData();
}));
var that = thisでスコープをアレする

ちょっと懐かしいやり方

var that = this;
$("#setting input[type='submit']").click(function(event) {
  event.preventDefault();
  that.putStoredData();
});

所感

今回の永続化の取得に関しては、複数のキーを簡単に取得出来るopensocial-jqueryのほうが好みだなぁと感じました。
今回の永続化の取得に関しては、最新版を使うとどちらも同じことが出来そうです。