2015-08-13 3 views
0

Я, конечно же, пытаюсь переместить мой сайт на Hack и XHP. Ниже приведена структура какой структуры кода я хочу добиться:Получите детей от XHPChild

<ui:backstageHeader> 
    <ui:backstageHeader-navItem href="/">stories</ui:backstageHeader-navItem> 
    <ui:backstageHeader-navItem href="/story/send">send a story</ui:backstageHeader-navItem> 
    <ui:backstageHeader-navItem href="/aboutus">support</ui:backstageHeader-navItem> 
</ui:backstageHeader> 

(Примечание::ui:backstageHeader-navItem в основном оказывает <a href={$this->:href}>{$this->getCHildren}</a> поэтому не нужно прикрепить его класс здесь.)

Ниже приведен код для :ui:backstageHeader:

final class :ui:backstageHeader extends :ui:base { 
    attribute :div; 
    children (:ui:backstageHeader-navItem)*; 

    protected function compose() { 
    $dom = 
    <section class="backstage-header"> 
     <div class="container"> 
     <div class="cell-logo"> 
      <a href="/"> 
      <span class="no23-logo-white"></span> 
      </a> 
     </div> 
     <div class="cell-navigation"> 
     </div> 
     <div class="cell-account"> 
      <div class="cell-login"> 
      <div id="siteNav-login">Autentificare</div> 
      </div> 
     </div> 
     </div> 
    </section>; 
    $mainContainer = $dom->getChildren("div")[0]; 
    $cellNavigation = $mainContainer->getChildren("div")[1]; 
    $navItems = <ul class="main-navigation"></ul>; 
    foreach($this->getChildren() as $child) { 
     $navItems->appendChild(<li>{$child}</li>); 
    } 
    $dom->appendChild($navItems); 

    return $dom; 
    } 
} 

Я использовал терминал для отладки моего кода, используя hhvm -m d <file.php>, и все было хорошо там; однако, когда я добираюсь до своего браузера, я получаю 500 заголовок ошибки. Это то, что говорит журнал:

Catchable fatal error: Hack type error: Could not find method getChildren in an object of type XHPChild at /var/www/res/ui/backstage-header.php line 25 

ошибка происходит от

$cellNavigation = $mainContainer->getChildren("div")[1]; 

Но, так или иначе, мне нужно добавить ul.main-navigation к div.cell-navigation от моего section.backstage-header.

Как я могу это сделать?

ответ

2

Не структурируйте свой код таким образом. Создал его изнутри, так что вам не нужно делать тонну нечитаемых звонков getChildren, которые ищут конкретных детей. Эти вызовы очень трудно читать, а супер негибкие, когда вы меняете структуру своего XHP. Вы бы не сделали что-то вроде node.firstChild.lastChild.lastChild.firstChild в JS DOM, не так ли? Нет, в JS есть лучший способ найти вещи по классу или ID; в XHP, вы можете просто создать его правильно, в первую очередь!

Я дам вам пример, но это не выглядит, как вы на самом деле использование$mainContainer или $cellNavigation, так что вы можете просто удалить эти два проблемных определения.

В стороне, вы действительно не должны получать ошибки своего типа как увлекательные смертельные от HHVM; это последний способ проверки. Попробуйте запустить контрольную панель hh_client, возможно, даже показывая ее результат в вашей среде IDE; это даст вам гораздо более быстрый итерационный цикл и гораздо больше информации, чем предоставляет HHVM.

1

Из моего опыта, appendChild очень подвержен человеческой ошибке. Это легче сделать что-то вроде:

$items = (new Vector($this->getChildren()))->map($child ==> <li>{$child}</li>); 
return <div id="container">{$items}</div>; 

Если вы хотите, чтобы обернуть детей в <li />.

Не уверен, что это сработает, но оно будет близко.

0

Pro tip: Вы можете назначать переменные из дерева XHP.

$root = 
    <div> 
    {$child = <span> 
     Text children 
    </span>} 
    </div>; 

Теперь $ ребенок уже установлен на <span> элемента.