ウィジェットのクラスをコーディングする方法

では次に、クラスの継承を用いてウィジェットのクラスを作成する方法を学んでいこう。 一般的には、ウィジェットクラスは「dijit._Widget」クラスと「dijit._Templated」クラスを多重継承して作成する。つまり、以下のような形になる。

    // _Widgetと_Templatedを継承してクラスを作成
    dojo.declare(
      "mycom.Hello",
      [dijit._Widget, dijit._Templated],
      {
        ...
      }
    );

dijit._Widgetは、すべてのウィジェットの親クラスだ。dijit._Templatedは、このクラスを継承することにより、HTMLテンプレートを用いてウィジェットの作成を行うことができる。

では、ウィジェットクラスのソースコードをすべて見てみよう。

    dojo.provide("mycom.Hello");

    dojo.require("dijit._Widget");
    dojo.require("dijit._Templated");

    dojo.declare(
      "mycom.Hello",
      [dijit._Widget, dijit._Templated],
      {
        // (1) HTMLテンプレートの指定
        templatePath: dojo.moduleUrl("mycom","templates/hello.html"),

        // (2) 以下はライフサイクルメソッド
        postMixInProperties: function() {
          console.log("PostMixInProperties");
          this.inherited(arguments);
        },
        buildRendering: function() {
          console.log("buildRendering");
          this.inherited(arguments);
        },
        postCreate: function() {
          console.log("PostCreate");
          this.inherited(arguments);
        },
        startup: function() {
          console.log("Startup");
          this.inherited(arguments);
        }
      }
    );

(1) HTMLテンプレートは、ウィジェットクラスの「templatePath」属性で指定する。dojo.moduleUrl()メソッドを使用することにより、実際のURLに依存せず、モジュールの検索パスからテンプレートを読み出すことが可能だ。

HTMLテンプレートファイルの内容は、先ほどと変わらない。

<div>
  Hello <span dojoAttachPoint="containerNode"></span>
</div>

(2) ウィジェットは固有の「ライフサイクル」を持っており、その状態に応じてウィジェット内のメソッドが呼び出されるようになっている。ここではライフサイクルメソッドの全てをオーバーライドして、ログの出力を行ってみた。

上記のライフサイクルメソッドは以下のような順番とタイミングで呼び出される。

  1. postMixInProperties() … ウィジェットの属性値は、ウィジェットクラス内のインスタンス変数としてアクセスできる (次の項を参照)。属性値からインスタンス変数にマップされた直後にこのメソッドは呼び出される。
  2. buildRendering() … ウィジェットのDOMノードを生成するために呼び出される。dijit._Templatedを継承していれば、HTMLテンプレートを用いたDOMノードの生成が自動的に行われるため、このメソッドをオーバーライドする必要はない。
  3. postCreate() … ウィジェットの生成が完了した直後に呼び出される。カスタムウィジェットの多くは、このメソッドをオーバーライドすることで、ウィジェットの初期化処理を実現する。
  4. startup() … ウィジェットの動作を開始する処理として、dojo.parserなどによって呼び出される。ウィジェットの生成処理と動作の開始が分けられていることで、複数のウィジェットの生成のみを行ってキャッシュする、などの柔軟な運用が可能となる。ContentPaneなどのレイアウト系ウィジェットは、多くの場合startup()の明示的な呼び出しを行うまで表示が行われない。

属性による値指定を行えるようにする

Dojoで提供されているウィジェットの多くは、属性を指定することにより、ウィジェットの振る舞いをさまざまに変更できる。

自作ウィジェットから属性値を取り扱うのは非常に簡単なので、トライしてみよう。先ほどのウィジェットを改良し、「Hello, 」に続く文字列を「name」属性でも指定できるようにしてみたい。

      <!-- 作成したウィジェットを使用 -->
      <div dojoType="mycom.Hello" name="Shumpei"></div>

1. ウィジェットクラス内に、属性に対応したプロパティを作成する

タグの属性値は、ウィジェットクラス内ではインスタンス変数としてアクセスする。そこでまず行うべきは、属性名と同じ名前のインスタンス変数をクラス内に作成することだ。

    dojo.declare(
      "mycom.Hello",
      [dijit._Widget, dijit._Templated],
      {
        ...(略)...

        name: "",

        ...(略)...
      }
    );

2. HTMLテンプレート内でプロパティの値を参照する

HTMLテンプレート内では、「${ }」と言う記法を用いてウィジェットクラスのプロパティを参照できる。

    <div>
      Hello <span dojoAttachPoint="containerNode">${name}</span>
    </div>