4 Stimmen

Gibt es eine bessere Möglichkeit, eine DOMElement->tagName Eigenschaft in php zu ändern?

Ich lief gerade in diese Gebäude ein Textbox-Steuerelement für meine MVC-Framework, wo kurz vor Abschluss des gesamten Dokuments ich PreRender auf alles aufrufen, die von ServerTag erbt (die wiederum von DOMElement erbt).

Die einzige Möglichkeit, die ich gefunden habe, um ein DOMElement abgeleitete Objekt TagName zu ändern ist, um es mit einem neuen mit allen Attributen synchronisiert, um die alte zu ersetzen.

So sieht das im Code aus:

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;
    }
}

Ist das wirklich die einzige Möglichkeit? Dieser Weg hat den eher unerwünschten Nebeneffekt, dass die gesamte Logik hinter dem Steuerelement aufgehoben wird.

2voto

joelhardi Punkte 10789

Ja, so müssen Sie es machen - der Grund dafür ist, dass Sie nicht nur den Wert eines einzelnen Attributs ändern wollen ( tagName ), ändern Sie das gesamte Element von einem Typ zu einem anderen. Eigenschaften wie tagName (oder nodeName ) und nodeType sind im DOM schreibgeschützt und werden beim Erstellen des Elements festgelegt.

Wenn Sie also ein neues Element erstellen und anstelle des alten verschieben, genau wie Sie es tun, mit DOMNode::replaceChild ist der richtige Vorgang.

Ich bin mir nicht sicher, was Sie mit "unerwünschter Nebeneffekt der Annullierung der gesamten Logik hinter dem Steuerelement" meinen - wenn Sie das klären, kann ich Ihnen vielleicht eine Anleitung dazu geben.

Es klingt wie Sie möglicherweise nicht haben möchten ServerTag erben von DOMElement und stattdessen möchten Sie möglicherweise diese beiden Objekte durch ein anderes Muster, wie z. B. Komposition (d. h. so ein ServerTag "hat ein" DOMElement anstelle von "ist ein" DOMElement) verknüpfen, so dass Sie lediglich das DOMElement-Objekt mit Ihrem ServerTag Textbox-Objekt zugeordnet ersetzen.

Längerfristig könnte es auch sein, dass Sie Probleme beim Kopieren der Attribute bekommen (z. B. textarea hat erforderliche Attribute, wie rows y cols dass input nicht).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X