2011-10-11 78 views
1

我目前正在學習symfony1.4,並且試圖以有限的成功導航教條的嵌套集合特性。我有一個類別表使用多樹的嵌套集行爲。我的類別樹數據可多達六個深...symfony1.4嵌套設置通過級別的導航

Categories: 
    columns: 
    category_name: 
     type: string(40) 
    actAs: 
    NestedSet: 
     hasManyRoots: true 
     rootColumnName: parent_id 

這些類別的產品,我想一個網頁通過類別進行過濾,以顯示到達葉是類產品如顯示根,如果選擇了一個根,然後顯示它的子項,那麼如果選擇了一個子項,則顯示它的子項等,直到你選擇一個葉子節點。 here's an image which may describe it better

我試圖構建過濾類別的2維數組,以傳遞給視圖...沒有成功。任何解決方案將有助於我的頭炸!

非常感謝,

搶。

回答

5

改寫

的改寫你的問題:你需要和他們的兄弟姐妹(您的節點與節點的每一個祖先)。

其他的改寫:你需要你的節點的所有祖先的所有孩子的(但不是所有他們的後代)

沿着而且,不要以爲你應該設置爲true hasManyRoots,除非你有幾家商店。現在讓我們假設你有一個根,你可以命名爲'shop'

這是第三個更簡單的改寫:所有你需要的是你節點的每個祖先的孩子(和愛情,根據披頭士)。

獲取數據

獲取祖先的數組(請參見爲什麼在最後§)很簡單:

$this->ancestors = $currentCategory->getNode()->getAncestors()->getData(); 

現在,讓我們來構建它會給你你所需要的查詢。假設你的模型被命名爲Category,而不是Categories(它確實應該)。

$q = CategoryTable::getInstance()->createQuery('c'); 
foreach ($this->ancestors as $ancestor) 
{ 
    // should work thanks to AND priority over OR 
    $q->orWhere('c.level = ?' $ancestor->getLevel() + 1) 
    ->andWhere('c.lft > ?' $ancestor->getLeftValue()) 
    ->andWhere('c.rgt < ?' $ancestor->getRightValue()) 
} 

如果你不明白這最後一件事是什麼,那麼你可能需要閱讀this excellent article about adjacency list model vs nested set model

現在好了,你有你的查詢,讓我們獲取結果:

$this->categoryTree = $q->execute(
    array(), 
    Doctrine_Core::HYDRATE_RECORD_HIERARCHY); 

O_o等待......最後一個參數是關於什麼的?在閱讀有關嵌套集的教義文檔時,您可能沒有聽說過它。這是因爲它在the page about data hydrators上有記錄。這非常糟糕,因爲HYDRATE_RECORD_HIERARCHY在處理嵌套集合時非常有趣。現在,您將$ categoryTree中所需的所有內容都視爲一個層次結構。無論你的樹有多深,只有兩個請求!我想可以寫在一個請求中,但我不知道如何。

注意:還有Doctrine_Core::HYDRATE_ARRAY_HIERARCHY,它水合到一個分層陣列,這是更快。如果您不需要調用提供不屬於對象一部分或者在運行時計算的東西的方法,則可以使用它。您只需在模板中使用數組而不是對象符號(例如,$categoryTree['children']

顯示數據

現在,在您_menu.php模板,這裏是你可以做什麼:

<?php 
array_shift($ancestors); 
include_partial('level', array(
    'children' => $categoryTree->get('__children'), 
    'ancestors' => $ancestors 
); 

而且在_level.php

<ul> 
<?php $selectedChild = array_shift($ancestors); 
foreach ($children as $child): 
    if ($isSelected = ($child->getId() == $selectedChild->getId())): 
    $grandChildren = $child->get('__children'); 
    endif; ?> 
    <li<?php if ($isSelected):?> class="selected"<?php endif?>> 
    <?php echo $child->getName() ?> 
    </li> 
<?php endforeach ?>: 
</ul> 
<?php if (count($ancestors)): 
    // RecursiviRecurRecuRecursiRRecursivityecursivityvityrsivitysivityty 
    include_partial('level', array(
     'children' => $grandChildren, 
     'ancestors' => $ancestors 
    ); 
endif; ?> 

我只是寫了這個未經測試任何事情,所以它從一開始就可能無法正常工作。只要讓我貼出你遇到的問題。祝你好運!

+0

你好嗎?任何意見?你解決了你的問題嗎? – greg0ire

+0

非常感謝greg!感謝您花時間給出這樣詳細的回覆。我使用我的Facebook帳戶創建了我的堆棧溢出帳戶,並且由於某種原因沒有通過電子郵件告訴我您的回覆...我會給它一個去,讓你知道我如何得到。 –

+0

太棒了!如果您卡住了,您可以使用您提出的代碼更新您的問題! – greg0ire