H2Databaseを追っかけていたりしたブログ

H2 database のリリースノートを読んだりとか。

closure-library始める2 uiコンポーネントについて

まず、コンポーネントを作ってみる。

参考。http://code.google.com/p/closure-library/wiki/IntroToComponents

参考のページとそのサンプルコードを見ればそれでいいような気もするが、ちょっと簡略化してちょっとずつ確認してみる。

goog.provide('hoge.Box');
goog.require('goog.ui.Component');

hoge.Box = function(opt_label,opt_domHelper){
  goog.ui.Component.call(this,opt_domHelper);
  this.label_ = opt_label || 'Click Me';
  this.initialize_();
}
goog.inherits(hoge.Box,goog.ui.Component);

hoge.Box.prototype.initialize_ = function(){
};

goog.provideで自分が何のクラスかを宣言して、goog.requireで依存を表現している。uiを作るので、goog.ui.Componentに依存している。

コンストラクタの最初でgoog.ui.Componentのコンストラクタを呼んでいる。で、goog.inheritsでhoge.Boxはgoog.ui.Componentを継承することを宣言している。次はDOMを構築する。

hoge.Box.prototype.createDom = function(){
  this.decorateInternal(this.dom_.createElement('div'));
};

createDomは実装必須。decorateInternalはオプション。createDomでは、このクラスのDOM表現のルートとなる要素をつくる。で、decorateInternalでは、外部から要素が与えられたときに、その要素を自分のルート要素として、必要なお膳立てを行う、という感じのようだ。ここでは、ルート要素を空のdivで作って、それ以外の装飾の部分はdecorateInternalに任せるという形になっている。いきなりthis.dom_とか出てきてなによ、と思うがAPIリファレンスを読むと、goog.domのショートカットだ。

hoge.Box.prototype.decorateInternal = function(element){
  this.setElementInternal(element);
  this.dom_.setProperties(element, {"style":"border: 1px solid black; width: 150px; background-color: gray; color: white; text-align: center; font-weight: bold;"});
  if(!this.getLabelText()){
    this.setLabelText(this.label_);
  }
};
hoge.Box.prototype.getLabelText = function(){
  if(!this.getElement()){
    return '';
  }
  return this.dom_.getTextContent(this.getElement());
};
hoge.Box.prototype.setLabelText = function(text){
  if(this.getElement()){
    this.dom_.setTextContent(this.getElement(), text);
  }
};

this.setElementInternal(element)が重要。closureのuiコンポーネントでは、DOM表現のルート要素はsetElementInternal(element)でセットして保持しておく。以降はgetElement()で取り出せる。getLabelText/setLabelTextはおまけ。

これで、実行してみる。app.jsに以下のように記述する。

goog.provide('hoge.App');
goog.require('hoge.Box');

hoge.App = function(){
  this.initialize_();
}
hoge.App.prototype.initialize_ = function(){
  var he = new hoge.Box();
  he.render(document.body);
};
new hoge.App();

なんかボタンみたいなものが表示できた。