Ajax.Updaterクラス

【抜粋】一部省略
Ajax.Updater = Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
  initialize: function(container, url, options) {
(省略)
  },
(省略)
    if (this.responseIsSuccess()) {
      if (this.onComplete)
        setTimeout(this.onComplete.bind(this), 10);
    }
  }
});

Ajax.UpdaterクラスはAjax.Requestクラスを継承しています。

initializeメソッド

  initialize: function(container, url, options) {
    this.containers = {
      success: container.success ? $(container.success) : $(container),
      failure: container.failure ? $(container.failure) :
        (container.success ? null : $(container))
    }

    this.transport = Ajax.getTransport();
    this.setOptions(options);

    var onComplete = this.options.onComplete || Prototype.emptyFunction;
    this.options.onComplete = (function(transport, object) {
      this.updateContent();
      onComplete(transport, object);
    }).bind(this);

    this.request(url);
  },

initializeメソッドをオーバーライドしています。

this.containersプロパティのオブジェクトは、successとfailureの二つのプロパティを持ちます。各プロパティに格納されるのは以下となります。

引数containerがIDまたは要素の場合(successとfailureプロパティを持たない) 引数containerがsuccessとfailureプロパティを持つオブジェクトの場合 引数containerがsuccessプロパティを持つがfailureプロパティを持たないオブジェクトの場合
this.containers.success 引数containerの要素($関数で処理したもの) 引数container.successの要素($関数で処理したもの) 引数container.successの要素($関数で処理したもの)
this.containers.failure 引数containerの要素($関数で処理したもの) 引数container.failureの要素($関数で処理したもの) null

つまり、Ajax.Updaterクラスの第一引数は、要素IDまたは要素か、successとfailureプロパティ(failureはなくても可)を持つオブジェクトになります。それぞれ、要素IDまたは要素を値として持ちます。これらがAjax.Updaterが受信したデータを表示する要素(または基準要素)となります。failureプロパティを省略するとエラー時には何も表示されません。

transportプロパティにXMLHttpRequestオブジェクトを格納し、optionsプロパティに引数optionsの各メソッド・プロパティを登録しているのはAjax.Requestクラスと同じです。

その後、一度optionsに登録されているonCompleteメソッドの関数を退避させ、改めてoptions.onCompleteメソッドで、後述するupdateContentメソッドと退避した関数を実行する関数を登録しています。

その後、Ajax.Requestから継承したrequestメソッドを呼び出します。

【例】
[test.htm]
<html>
<head>
<title></title>
<style>
div{
  border:solid blue 2px;
  height:10px;
}
</style>
<script language="javascript" src="./prototype.js" charset="utf-8"></script>
</head>
<body>
<div id="test1"></div>
<div id="test2"></div>
<input type="text" id="url" value="test.txt"/>
<!--ID指定-->
<button onclick="new Ajax.Updater('test1', $('url').value);">TEST1</button>
<!--要素指定-->
<button onclick="new Ajax.Updater($('test1'), $('url').value);">TEST2</button>
<!--success、failureを指定-->
<button onclick="new Ajax.Updater({success:'test1', failure:'test2'},
	                         $('url').value);">TEST3</button>
<!--successのみ指定-->
<button onclick="new Ajax.Updater({success:$('test1')},
	                         $('url').value);">TEST4</button>
<button onclick="$('test1').innerHTML='';
                 $('test2').innerHTML='';">クリア</button>
</body>
</html>
---------------------------------------------------------------------------------
[test.txt]UTF-8で記述すること
Ajax.Updaterのテスト

TEST1〜4のどのボタンを押しても、最初のDIVにtest.txtの内容が表示されます。テキストボックスの内容を存在しないパスにすると、TEST1と2では最初のDIVに、TEST3では次のDIVにNotFoundエラー画面が表示されます。TEST4ボタンではなにも表示されません。(NotFoundエラー画面はWebサーバ経由でないと表示されません)

updateContentメソッド

【抜粋】
  updateContent: function() {
    var receiver = this.responseIsSuccess() ?
      this.containers.success : this.containers.failure;
    var response = this.transport.responseText;

    if (!this.options.evalScripts)
      response = response.stripScripts();

    if (receiver) {
      if (this.options.insertion) {
        new this.options.insertion(receiver, response);
      } else {
        Element.update(receiver, response);
      }
    }

optionsプロパティのonCompleteメソッドから呼び出されるメソッドです。

Ajax.Baseから継承しているresponseIsSuccessメソッドで、受信の成否を判定します。成功ならthis.containers.successの要素を、失敗ならthis.containers.failureの要素を対象とします。

optionsプロパティのevalScriptsがfalseまたはnull(undefined)であれば、受信データからスクリプトタグを取り除いています。Ajax.Updaterではoptionsに登録できるプロパティにこのevalScriptsが追加されています(もう一つinsertionが追加されています。後述)。

対象要素がnullでない場合、データの表示処理を実行します。optionsプロパティのオブジェクトにinsertionプロパティが定義されている場合は、その値のクラスのインスタンスを作成します。これがAjax.Updaterで追加されたoptionsに登録できるもう一つのプロパティです。insertionは以下の値を取ることができます。

値(文字列ではなく、クラス) 動作
Insertion.Before 対象要素の直前に追加。
Insertion.Top 対象要素内の先頭に追加。
Insertion.Bottom 対象要素内の末尾に追加。
Insertion.After 対象要素の直後に追加。

各クラスについては後述します。

insertionが指定されていない場合は対象要素自体に受信データを流し込みます。Element.updateについても後述になりますが、要素にデータを流し込むと同時に、データにスクリプトタグがあるとこれを実行する、という動作をします。

最後に受信成功時に、自オブジェクトにonCompleteメソッドがあれば0.01秒後に実行する、というコードがあるのですが・・・。自オブジェト(this直下)にonCompleteメソッドなんてないし、登録するところもないような? (次のAjax.PeriodicalUpdaterクラスならそれらしい箇所があるのですが・・・) どうやって登録するんでしょうか・・・。

【例】
[test.htm]
<html>
<head>
<title></title>
<style>
div{
  border:solid blue 2px;
  margin:10px 10px 10px 10px:
  padding:10px 10px 10px 10px;
}
</style>
<script language="javascript" src="./prototype.js" charset="utf-8"></script>
</head>
<body>
<div id="test">
  <div>****</div>
</div>
<!--要素直前-->
<button onclick="new Ajax.Updater('test', 'test.txt',
                                  {insertion:Insertion.Before});">TEST1</button>
<!--要素内先頭-->
<button onclick="new Ajax.Updater('test', 'test.txt',
                                  {insertion:Insertion.Top});">TEST2</button>
<!--要素内末尾-->
<button onclick="new Ajax.Updater('test', 'test.txt',
                                  {insertion:Insertion.Bottom});">TEST3</button>
<!--要素直後-->
<button onclick="new Ajax.Updater('test', 'test.txt',
                                  {insertion:Insertion.After});">TEST4</button>
<!--スクリプト実行-->
<button onclick="new Ajax.Updater('test', 'test.txt',
                                  {evalScripts:true});">TEST5</button>
</body>
</html>
-----------------------------------------------------------------------------
[test.txt]UTF-8で記述すること
<div>Ajax.Updaterのテスト。</div>
<script>
  $('test').style.backgroundColor = "yellow";
  alert("スクリプト実行");
</script>

TEST1〜4のボタンでそれぞれ指定した場所に受信データを挿入します。スクリプトは無視されます。TEST5のボタンは要素の中身を書き換えた後、背景を黄色にしてアラートを出しています。