2008-10-26 57 views
3

我只是碰到了這個建築對我的MVC框架,在剛剛敲定整個文檔之前,我打電話的PreRender在從ServerTag(這反過來從一個DOMElement繼承)繼承一切TextBox控件。有沒有更好的方式來更改PHP中的DOMElement-> tagName屬性?

我發現改變一個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; 
    } 
} 

那真的只有這樣,才能做到這一點?這種方式具有將控制背後的所有邏輯置零的相當不希望的副作用。

回答

2

是的,你如何做到這一點 - 原因是你不只是改變一個屬性的值(tagName),你實際上是將整個元素從一種類型改變爲另一種類型。如tagName(或nodeName)和nodeType屬性爲只讀的DOM,當你創建的元素設置。

因此,創建一個新元素並按照您的要求移動到原來的位置,使用DOMNode::replaceChild即可正確操作。

我不確定你的意思是「無效的控制背後的所有邏輯的副作用」 - 如果你澄清我可能會給你指導。

這聽起來像你可能不想讓ServerTag從DOMElement繼承,而是你可能想通過其他模式,如組合(即所以一個ServerTag「有一個」DOMElement而不是「是一個「DOMElement),以便您僅替換與您的ServerTag文本框對象關聯的DOMElement對象。

或者更長次的猜測是,你可能會運行到剛剛複製的屬性的問題(即textarea已要求屬性,如rowscols,那input沒有)。

+0

這幾乎是我想通了,即使我不認爲它應該工作方式 – Kris 2008-11-04 22:47:02

相關問題