我正在尝试实现一个简单的菜单组合模式。
以下是我提出的课程。
菜单项:
namespace MYNAME\MYBUNDLE\Entity;
use MYNAME\MYBUNDLE\Menu\MenuComponent;
class MenuItem implements MenuComponent
{
private $id;
private $name;
private $path;
private $parent;
private $visible;
private $createdOn;
private $templating;
private $attr;
private $children;
private $website;
private $position = 1;
public function __construct($name = null, $path = null, $attr = array(), $visible = true)
{
$this->name = $name;
$this->path = $path;
$this->visible = $visible;
$this->attr = $attr;
$this->createdOn = new \DateTime;
}
public function prePersist()
{
$this->createdOn = new \DateTime;
}
public function build()
{
$data['menu_item'] = $this;
$data['options'] = $this->attr;
if($this->hasChildren())
return $this->templating->render('MYBUNDLE:Menu:menu_dropdown.html.twig', $data);
if($this->isChild())
return $this->parent->getTemplating()->render('MYBUNDLE:Menu:menu_item.html.twig', $data);
return $this->templating->render('MYBUNDLE:Menu:menu_item.html.twig', $data);
}
public function __toString()
{
return $this->name;
}
public function setTemplating($templating)
{
$this->templating = $templating;
}
/**
* @return bool
*/
public function isChild()
{
return $this->hasParent();
}
/**
* @return bool
*/
public function hasParent()
{
return isset($this->parent);
}
/**
* @return bool
*/
public function hasChildren()
{
return count($this->children) > 0;
}
}
如果省略吸气剂和制定者以使其在这里缩短一点。 正如您所看到的,这是实体并且它包含一个build()函数,但是这个函数使用了我认为不应该在实体中的render方法。
MenuController
<?php
namespace MYNAME\MYBUNDLE\Controller;
use MYNAME\MYBUNDLE\Menu\Menu;
use MYNAME\MYBUNDLE\Entity\MenuItem;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class MenuController extends Controller
{
public function generateAction()
{
$menu = new Menu($this->get('templating'));
// load menu items
$items = $this->getDoctrine()->getRepository('MYBUNDLE:MenuItem')->findOrdered();
foreach($items as $item)
{
if(!$item->hasParent())
$menu->add($item);
}
return new Response($menu->build());
}
}
调用MenuController来渲染菜单:
{{ render(controller('MYBUNDLE:Menu:generate')) }}
我也希望这是不同的,因为它看起来并不正确。也许创建一个枝条功能来渲染菜单会更好吗?
MenuComponent中:
namespace MYNAME\MYBUNDLE\Menu;
interface MenuComponent {
public function build();
}
菜单:
namespace MYNAME\MYBUNDLE\Menu;
class Menu implements MenuComponent
{
private $children;
private $templating;
public function __construct($templating)
{
$this->templating = $templating;
}
public function add(MenuComponent $component)
{
$component->setTemplating($this->templating);
$this->children[] = $component;
}
public function build()
{
return $this->templating->render('MYBUNDLE:Menu:menu.html.twig', array("menu_items" => $this->children));
}
}
菜单包含MenuComponents并将首先渲染菜单,在每个MenuItem中调用它的build()方法。
我认为最好从我的MenuItem实体中删除渲染逻辑并将其放在其他地方,但是我无法弄清楚如何在此设计模式中正确执行此操作。
感谢任何帮助或建议。