コンポーネント ========= Yiiアプリケーションは、仕様に基づいて書かれたオブジェクトである コンポーネント群によって成り立っています。コンポーネントは [CComponent]のインスタンスか、派生クラスです。 コンポーネントの使用は大概の場合、プロパティへのアクセスやイベントの発生、 ハンドリングを伴います。基底クラスである[CComponent] は、どのようにプロパティやイベントの定義を行うかを指定しています。 コンポーネント プロパティ ------------------ コンポーネントプロパティはオブジェクトのパブリックなメンバ変数 の様なものです。値を割り当てたり、読み取る事ができます。以下は例です。 ~~~ [php] $width=$component->textWidth; // textWidthプロパティを取得 $component->enableCaching=true; // enableCachingプロパティをセット ~~~ コンポーネントプロパティを定義する為には、単純にコンポーネントクラスの パブリックメンバ変数を宣言すれば良いでしょう。もっと柔軟なやり方は、 下記の様にゲッターやセッターメソッドを定義する方法です: ~~~ [php] public function getTextWidth() { return $this->_textWidth; } public function setTextWidth($value) { $this->_textWidth=$value; } ~~~ これらのコードは、書き込み可能な `textWidth` プロパティ (この名前の大文字小文字は区別されません)を定義しています。プロパティの値を 読み取る際は `getTextWidth()` が呼ばれ、プロパティの値が返されます;同様に、 プロパティに書き込む際は `setTextWidth()` が呼ばれます。もし セッターメソッドが未定義の場合、プロパティは読み取りのみが可能となり、 書き込みは例外を発生させるでしょう。プロパティの値を決める際に、ゲッター、 セッターメソッドを使用する事は、プロパティの読み込みや書き込み時に 実行可能なロジック(例えばバリデーションの実行、イベントの発生など) の追加において有益です。 >Note|注意: セッター/ゲッターメソッドで定義されたプロパティとクラスの メンバ変数には少し違いがあります。前述の名前は、大文字小文字が 区別されませんが、後述は大文字小文字が区別されます。 コンポーネントイベント --------------- コンポーネントイベントは、('event handlers'と呼ばれる)メソッドを 値として取る特別なプロパティです。メソッドをイベントに結びつける (割り当てる)事によって、イベントが発生した場所から自動的にメソッドが 呼ばれることになります。このように、コンポーネントの振る舞いは、 コンポーネントの開発時には予期しなかったであろう動作に改造できます。 コンポーネントイベントは、`on` で始まる名前のメソッドを定義する事によって 定義されます。ゲッター/セッター メソッドによって定義されるプロパティ名と 同様に、イベント名は、大文字小文字を区別しません。下記のコードは、 `onClicked`イベントを定義しています: ~~~ [php] public function onClicked($event) { $this->raiseEvent('onClicked', $event); } ~~~ `$event` の箇所はイベントパラメータを表す [CEvent]のインスタンスか、 その子クラスです。 下記の様にメソッドとイベントを結びつけることが出来ます: ~~~ [php] $component->onClicked=$callback; ~~~ `$callback` の箇所は、PHPのコールバックの正式な書式を参照します。 グローバル関数か、クラスメソッドを取ることができます。もしクラスメソッド であるならば、コールバックは: `array($object,'methodName')` のような配列が 与えられなければなりません。 イベントハンドラーのシグネイチャー(指示の書式)は下記の様な書式 でなければなりません: ~~~ [php] function methodName($event) { ...... } ~~~ `$event` の箇所は(`raiseEvent()`のコールによって生じる)イベントを表す パラメータです。`$event`パラメータは[CEvent]のインスタンスか、 その派生クラスです。これには誰がイベントを発生させたかの情報が 最低限含まれることになります。 もし今 `onClicked()` をコールしたとすると、`onClicked` イベントが (`onClicked()`の中で)発生し、結びついたイベントが自動的に 呼び出されるでしょう。 イベントは複数のハンドラに結びつける事ができます。イベントが発生した際、 ハンドラはイベントに結び付けられた順番で呼び出されます。もし、 あるハンドラが、残りのハンドラが呼び出される事を防ごうとする場合、 [$event->handled|CEvent::handled]を true にセットする事が出来ます。 コンポーネントビヘービア ------------------ バージョン1.0.2からコンポーネントに対して[mixin](http://en.wikipedia.org/wiki/Mixin)のサポートが追加されました。 さらにコンポーネントにひとつ又は複数のビヘービアをアタッチすることが可能になりました。 *ビヘービア*は、特殊化する(つまり通常のクラス継承)代わりに機能を集める手段により、 アタッチされたコンポーネントによってメソッドが'継承された'オブジェクトです。 コンポーネントには複数のビヘービアをアタッチでき、すなわち'多重継承'を達成することができます。 ビヘービアクラスは[IBehavior]インタフェースを実装する必要があります。多くのビヘービアは[CBehavior]ベースクラスから継承されます。 ビヘービアが[モデル][model](/doc/guide/basics.model)にアタッチされる場合、[CModelBehavior]または[CActiveRecordBehavior] から継承され、それらはモデルに固有な付加的な機能を実装しています。 ビヘービアを使うには、ビヘービアの[attach()|IBehavior::attach]メソッドを呼出すことにより、最初にコンポーネントにアタッチさられなければなりません。 次にコンポーネントを通してビヘービアのメソッドを呼ぶことができます。 ~~~ [php] // $nameはコンポーネントのビヘービアをユニークに確認します $behavior->attach($name,$component); // test()は$behaviorのメソッドです $component->test(); ~~~ アタッチされたビヘービアは、コンポーネントの通常のプロパティのようにアクセスすることができます。 たとえば`tree`と呼ばれるビヘービアがあるコンポーネントにアタッチされる場合、 このビヘービアオブジェクトへのリファレンスを以下を使うことで得ることができます。 ~~~ [php] $behavior=$component->tree; // $behavior=$component->asa('tree'); // と等価 ~~~ そのメソッドがコンポーネントを通して利用できないようにするため、ビヘービアは一時的に使用不能とすることができます。 たとえば、 ~~~ [php] $component->disableBehavior($name); // 以降の文は例外を起します $component->test(); $component->enableBehavior($name); // これで動きます $component->test(); ~~~ 同じコンポーネントに付けられる2つのビヘービアには同じ名前のメソッドがあるかもしれません。 この場合は最初にアタッチさられたビヘービアのメソッドが優位となります。 [イベント](#component-event)と合せて使われた場合にはビヘービアはさらに強力です。 コンポーネントに付けられるとき、ビヘービアは一部の自分のメソッドをコンポーネントのいくつかのイベントにアタッチすることができます。 そうすることによって、ビヘービアはコンポーネントの通常の実行フローを観察するか、変える機会を得ます。