Есть ли лучший способ изменить свойство DOMElement-> tagName в php? - PullRequest
3 голосов
/ 26 октября 2008

Я только что наткнулся на это построение элемента управления Textbox для моей инфраструктуры MVC, где непосредственно перед завершением всего документа я вызываю PreRender для всего, что наследуется от ServerTag (который, в свою очередь, наследует от DOMElement).

Единственный способ, которым я нашел, чтобы изменить tagName производного объекта DOMElement, это заменить его новым со всеми атрибутами, синхронизированными со старым.

Вот как это выглядит в коде:

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

Это действительно единственный способ сделать это? Этот способ имеет довольно нежелательный побочный эффект - обнуление всей логики, лежащей в основе управления.

1 Ответ

2 голосов
/ 29 октября 2008

Да, вот как вы должны это сделать - причина в том, что вы не просто изменяете значение одного атрибута (tagName), вы фактически меняете весь элемент с одного типа на другой. Такие свойства, как tagName (или nodeName) и nodeType доступны только для чтения в DOM и устанавливаются при создании элемента.

Итак, создание нового элемента и перемещение на место старого точно так же, как вы делаете, с DOMNode::replaceChild, является правильной операцией.

Я не уверен, что вы подразумеваете под "нежелательным побочным эффектом обнуления всей логики, лежащей в основе управления" - если вы поясните, я мог бы дать вам руководство там.

Звучит так, как будто вы не хотите, чтобы ServerTag наследовал от DOMElement, и вместо этого вы можете захотеть связать эти два объекта с помощью некоторого другого шаблона, такого как композиция (т. Е. У ServerTag есть «DOMElement вместо« is a » DOMElement), так что вы просто заменяете объект DOMElement, связанный с вашим объектом текстового поля ServerTag.

Или более длительное предположение: у вас могут возникнуть проблемы с простым копированием атрибутов (т. Е. textarea имеет обязательные атрибуты, такие как rows и cols, которых у input нет).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...