5

私は、高レベルの抽象化でフォームを生成することを含むアプリケーション(CMSアプリ)に取り組んでいます。CFormModelオブジェクトを動的に作成し、フォームフィールドをオンザフライで設定したいと思います。これは、CFormModelを拡張し、フォームフィールド(Yii用語の「属性」)を表すクラスプロパティを動的に作成することで実現できると思います。

説明のために、次のクラス(ファイルで定義)でログインフォームを指定する代わりに:

// From: http://www.yiiframework.com/doc/guide/1.1/en/form.model
class LoginForm extends CFormModel
{
    public $username;
    public $password;
    public $rememberMe=false;

    private $_identity;

    public function rules()
    {
        return array(
            array('username, password', 'required'),
            array('rememberMe', 'boolean'),
            array('password', 'authenticate'), // assume function authenticate defined elsewhere
        );
    }
}

私はそれを次のようにやりたいです:

class MyFormModel extends CFormModel {

    protected $_rules = array();

    public function __construct($attributes=array(), $rules=array()) {

        foreach ($attributes as $i => $attr) {
            $this->{$attr} = ???; // <<== This is the key here
        }

        // pass in array of rules as described in Yii doc for CFormModel
        $this->_rules = $rules;
    }

    public function rules() {
        return $_rules;
    }
}

そして、必要に応じて次のように呼び出します。

$myModelObj = new MyFormModel($attr, $rules);

どこ :

$attr = array(
            'username',
            'rememberMe',
            'password',
        );
$rules = array(
            array('username, password', 'required'),
            array('rememberMe', 'boolean'),
            array('password', 'authenticate'), // assume function authenticate defined elsewhere
        );

私が達成しようとしていることに注意してください。どのファイルにも「LoginClass」は記述されておらず、コードでオンザフライで作成されています。

これにより、次のようなことを行うフォームを(ビューで)作成することができます。

// based on http://www.yiiframework.com/doc/guide/1.1/en/form.view
<?php echo $wForm->textField($myModelObj,'username'); ?>

私はこれを試しましたが、$ this->{$attr}行が次のように失敗しています。

Property "MyFormModel.username" is not defined.

実際、その行のコードは次のとおりです。

$this->{$attr};

??? これに何を割り当てるかがよくわからないことを示します。Yiiのドキュメントの例では、フィールドをパブリッククラス変数として定義しているだけです。

魔法の方法を使うべきですか?

私がここでやろうとしていることは可能ですか?

4

1 に答える 1

5

ご存知かもしれませんが、YiiはOOPオーバーロードを使用してARのようなプロパティを解決します。

ここで行う必要があることは、Yiiが内部で行うことと似ています。

ハードコードされたプロパティを定義して、配列のようにすべてのカスタムプロパティを保存します。$_data

このデータは配列になり、実行時に追加したすべての属性を保持します。最初にプロパティ所有者からプロパティ名を解決するために、Yiiのようにマジックメソッド(setters、getters、isset)を上書きして、検証に挑戦する必要がある場合があります$_data

CActiveRecordにあるある種のコードは、それらすべての__XXXようなメソッドを探します。

ARプロパティの処理をカスタムクラスに複製すると、これらすべてが自分のレベルで実行され、マジックメソッドがそれを解決しないときにYiiにフォールバックします。

また、多くの一般的な関数を動作クラスに委任できるため、動作についても調べます。

コンポーネントの動作の使用

コンポーネントはミックスインパターンをサポートし、1つまたは複数の動作でアタッチできます。ビヘイビアーは、特殊化(つまり、通常のクラス継承)の代わりに機能を収集する手段を介して、アタッチされたコンポーネントによってメソッドを「継承」できるオブジェクトです。コンポーネントはいくつかの動作でアタッチできるため、「多重継承」を実現できます。

ビヘイビアークラスはIBehaviorインターフェースを実装する必要があります。ほとんどの動作はCBehavior基本クラスから拡張できます。ビヘイビアーをモデルにアタッチする必要がある場合は、モデルに固有の追加機能を実装するCModelBehaviorまたはCActiveRecordBehaviorから拡張することもできます。

ビヘイビアーを使用するには、ビヘイビアーのattach()メソッドを呼び出して、最初にビヘイビアーをコンポーネントにアタッチする必要があります。次に、コンポーネントを介して動作メソッドを呼び出すことができます。

// $name uniquely identifies the behavior in the component
$component->attachBehavior($name,$behavior);
// test() is a method of $behavior
$component->test();

アタッチされた動作には、コンポーネントの通常のプロパティのようにアクセスできます。たとえば、treeという名前のビヘイビアがコンポーネントにアタッチされている場合、次を使用してこのビヘイビアオブジェクトへの参照を取得できます。

$behavior=$component->tree;
// equivalent to the following:
// $behavior=$component->asa('tree');

ビヘイビアーを一時的に無効にして、そのメソッドをコンポーネントから利用できないようにすることができます。例えば、

$component->disableBehavior($name);
// the following statement will throw an exception
$component->test();
$component->enableBehavior($name);
// it works now
$component->test();

同じコンポーネントにアタッチされた2つのビヘイビアーに、同じ名前のメソッドがある可能性があります。この場合、最初にアタッチされた動作の方法が優先されます。

イベントと一緒に使用すると、動作はさらに強力になります。ビヘイビアーは、コンポーネントにアタッチされると、そのメソッドの一部をコンポーネントの一部のイベントにアタッチできます。そうすることで、動作はコンポーネントの通常の実行フローを監視または変更する機会を得ます。

ビヘイビアのプロパティには、接続されているコンポーネントを介してアクセスすることもできます。プロパティには、パブリックメンバー変数と、動作のゲッターやセッターを介して定義されたプロパティの両方が含まれます。たとえば、ビヘイビアーにxyzという名前のプロパティがあり、ビヘイビアーがコンポーネント$aにアタッチされている場合。次に、式$a->xyzを使用して動作のプロパティにアクセスできます。

詳細:
http ://www.yiiframework.com/wiki/44/behaviors-events
http://www.ramirezcobos.com/2010/11/19/how-to-create-a-yii-behavior/

于 2012-07-04T06:43:51.497 に答える