Zend Frameworkによるツリーナビゲーション

大規模なプロジェクトには大きな問題があります-遅かれ早かれその内容は混乱に変わります(ほとんどの場合、これはバックエンドを指します。通常、すべてが前面で問題ないためです)。 プロジェクトの成長に伴い、その階層構造はより複雑になり、制御や作業が難しくなります。そのため、ツリー形式のナビゲーション出力を使用する必要があります。 プロジェクトのすべてのコンテンツが階層形式で表示される場合、非常に便利ですよね?



挑戦する



ツリーナビゲーションを実装します。 ツリーのネストは無制限です。



データベース





MySQLテーブル


CREATE TABLE IF NOT EXISTS `navigation` (

`nav_id` smallint(5) unsigned NOT NULL auto_increment,

`nav_parent` smallint(5) unsigned NOT NULL default '1',

`nav_title` varchar(200) NOT NULL,

PRIMARY KEY (`nav_id`),

KEY `nav_parent` (`nav_parent`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;



ALTER TABLE `navigation`

ADD CONSTRAINT `navigation_ibfk_1` FOREIGN KEY (`nav_parent`) REFERENCES `navigation` (`nav_id`) ON DELETE CASCADE ON UPDATE CASCADE;









多くの人がすでに推測しているように、このテーブルには再帰的な外部キーがあります。 コンテンツテーブルは外部キーナビゲーションテーブルに添付されますが、考慮しません。 このことは非常に明白です。



実装





ほとんどの場合、htmlをphpコードでエスケープし、適切なタイミングで出力できます。 ノードが次の形式の場合、これは許容されます。



html:

<li>

<a href="#">Pangram</a>

</li>









php + html:

<?php

$node = "<li><a href=\"#\">Pangram</a></li>"

?>







すべて順調ですが、追加のコードを入力する必要がある場合はどうでしょうか?



html:

<li class="menulayer" id="navigation_item_46">

<a href="#" onclick="myFunction(); return false;">Pangram</a>

</li>









php + html:

<?php

$node = "<li class=\"menulayer\" id=\"navigation_item_46\"><a href=\"#\" onclick=\"myFunction(); return false;\">Pangram</a></li>"

?>







追加するものはありますか? レイアウトデザイナーは長い間不満を感じると思います。 特に自分のコードではなく、PHPコードをいじりたい人はほとんどいません。



しかし、解決策は存在します。 ヘルパーを使用する必要があります。



ヘルパークラス


<?php

class MY_View_Helper_NavigationTree{

private $tree;

public $view;



public function setView(Zend_View_Interface $view){

$this->view = $view;

}



public function scriptPath($script){

return $this->view->getScriptPath($script);

}



/**

* @access public

* @param array ,

* @param integer ,

* @param array

* @return mixed

*/

public function navigationTree($tree, $id, array $args){

$this->tree = $tree;

return $this->getTree($id, $args);

}



/**

* @access private

* @param integer ,

* @param array

* @return mixed

*/



private function getTree($id, array $args){

$nodes = array();

foreach ($this->tree as $node){

if($node['nav_id'] != 1){

if($node['nav_parent'] == $id){

$nodes[] = $node;

}

}

}



return $this->view->partial('navigation/_partial/item.phtml', array(

'nodes' => $nodes,

'tree' => $this->tree,

'baseUrl' => $args['baseUrl']

));

}

}

?>









コントローラー


public function indexAction(){

$menu = new navigation();

$this->view->tree = $menu->fetchAll();

}











対応するアクションに対して、ビューを実装し、ヘルパーを呼び出します。



「ルート」の挑戦


<?= $this->navigationTree($this->tree, 1, array('baseUrl' => $this->baseUrl))?>









ネストされたビュー


<? foreach($this->nodes as $item) : ?>

<li class="menulayer" id="navigation_item_<?= $item['nav_id'] ?>">

<a href="#" onlclick="myFunction(); return false;">

<?= $this->escape($item['nav_title']) ?>

</a>

<ul id="treeitem_<? echo $item['nav_id']?>">



<?= $this->navigationTree($this->tree, $item['nav_id'], array('baseUrl' => $this->baseUrl)) ?>

</ul>

</li>

<? endforeach ?>









その結果、htmlコードを簡単に変更できます。

私は次のようなものを得ました:

画像



PS素材を準備してくれたonthefly habrayuzerに感謝します。



All Articles