DEVELOPMENTOR*LEARNING RESOURCE LAB.

ソフトウェア開発現場の視点からソフトウェアと開発者の価値を高める「ホットな何か」をお届けします。(休止)

Lyase.View Ajax指向のシンプルテンプレートエンジン(その4)

2006年11月21日 | prototype cast

Lyase.View Ajax指向のシンプルテンプレートエンジン(その3)」まではLyase.Viewの使い方を紹介しました。ここではLyase.Viewをより深く理解するため、Lyase.Viewのソースコードを読みながらその特徴に迫ります。

↓Lyase.Viewがテンプレートの文字列を解析するソースコードです。Lyase.Viewはテンプレートを解析しながら、そのテンプレートをJavaScriptコードに変換するという方法を使っています。

「new Function("context", parsed.join(""))」とあるように、Lyase.Viewは1つのテンプレートの文字列から1つのJavaScript関数を生成します。Functionオブジェクトを使って、動的にJavaScript関数を生成しているのがポイントです。Functionオブジェクトってこういう使い方もあるんですね。詳しくは「Mozilla Developer Center」の「Core JavaScript 1.5 Reference」を見てください。

Lyase.View = {
  _cache : {},
  parse : function(template, id) {
    var self = Lyase.View,parsed = ["var __out=[],render = Lyase.View.render;"]
    var tokens = template.split("<%");
    for(var i = 0, l = tokens.length; i<l; i++) {
      var token = tokens[i];
      if(token.indexOf("%>") == -1){
        parsed.push(self._string(token));
        continue;
      }
      var parts = token.split("%>");
      parsed.push(self[(parts[0].charAt(0) == "=")?"_value":"_code"](parts[0]));
      parsed.push(self._string(parts[1]));
    }
    parsed.push("return __out.join('');");
    var templateFunc = new Function("context", parsed.join(""));
    if(id) self._cache[id] = templateFunc;
    return templateFunc;
  },

テンプレートの文字列から生成したFunctionオブジェクトは、テンプレートの識別子に関連付けてキャッシュしています。「using innerHTML(ページ中の要素として)」のときは要素IDを、「using a template file(外部ファイルとして)」のときはファイルパスを識別子に使います。そのため、同じテンプレートを繰り返し使ったとしても、テンプレートを解析するのは1度だけです。ただし例外があり、「using text(JavaScriptの文字列として)」のときはキャッシュされません。

  render : function(options, values) {
    var self = Lyase.View, template, id;
    if(options.text) return self.parse(options.text, null)(values);
    if(options.element) var element = $(options.element);
    id = (options.file) ? options.file : element.id;
    if(self._cache[id]) return self._cache[id](values);
    if(options.element) {
      template = self._elementTemplate(element);
    }else {
      template = (new Ajax.Request(options.file,{asynchronous : false})).transport.responseText;
    }
    return self.parse(template, id)(values);
  },

「using a template file(外部ファイルとして)」のときはAjax.Request(prototype.js)を使って、テンプレートを外部ファイルから取得しますが、そのときHTTPサーバ側でエラーが発生しても、そのエラーレスポンスの内容をテンプレートして解釈しています。この振る舞いが許容できないときは、1例として次のようにソースコードを改良してエラーが発生したときの振る舞いを追加するとよいでしょう。

  var request = new Ajax.Request(options.file, {asynchronous : false}).transport;
  template = request.status!=200
    ? '...'
    : request.responseText;

Lyase.Viewの紹介は今回(その4)でおしまいです。


最新の画像もっと見る