4

MVCフレームワーク用のTextboxコントロールを構築しているところに出くわしました。ドキュメント全体を完成させる直前に、ServerTagから継承する(DOMElementから継承する)すべてに対してPreRenderを呼び出します。

DOMElement派生オブジェクトのtagNameを変更する唯一の方法は、すべての属性が古いものと同期された新しいオブジェクトに置き換えることです。

これはコードでどのように見えるかです:

protected function PreRenderTextarea( WebPage $sender )
{
    $textarea = $sender->createElement( 'textarea' );
    foreach( $this->attributes as $attribute )
    {
        if ( $attribute->name == 'value' )
        {
            $textarea->nodeValue = $attribute->value;
        }
        else
        {
            $textarea->setAttribute( $attribute->name, $attribute->value );
        }
    }
    $this->parentNode->replaceChild( $textarea, $this );
}

public function OnPreRender( WebPage $sender )
{
    parent::OnPreRender();
    $this->setAttribute( 'value', $this->Value );

    switch( $this->Mode )
    {
        case 'normal' : 
            $this->setAttribute( 'type', 'text' ); 
            break;
        case 'password' : 
            $this->setAttribute( 'type', 'password' ); 
            break;
        case 'multiline' : 
            $this->PreRenderTextarea( $sender ); 
            return; 
            break;
    }
}

それは本当にそれをする唯一の方法ですか?この方法には、コントロールの背後にあるすべてのロジックを無効にするという、かなり望ましくない副作用があります。

4

1 に答える 1

2

はい、これはあなたがそれをしなければならない方法です-理由はあなたがただ単一の属性(tagName)の値を変更しているのではなく、実際に要素全体をあるタイプから別のタイプに変更しているからです。tagName(またはnodeName)などのプロパティ nodeTypeはDOMで読み取り専用であり、要素の作成時に設定されます。

したがって、新しい要素を作成し、古い要素の代わりに、を使用して実行しているのとまったく同じように移動するDOMNode::replaceChildのが正しい操作です。

「コントロールの背後にあるすべてのロジックを無効にすることの望ましくない副作用」が何を意味するのかわかりません。明確にすれば、そこでガイダンスを提供できる可能性があります。

ServerTagにDOMElementから継承させたくないようですが、代わりに、これら2つのオブジェクトをコンポジションなどの他のパタ​​ーンでリンクしたい場合があります(つまり、ServerTagは「isa」DOMElementではなく「has」DOMElementを持っています)。 ServerTagTextboxオブジェクトに関連付けられているDOMElementオブジェクトを置き換えるだけです。

または、より長期的な推測では、属性をコピーするだけで問題が発生する可能性があります(つまり、 andなどのtextarea必要な属性がありますが、そうではありません)。rowscolsinput

于 2008-10-29T11:13:34.177 に答える