Логика хлебных крошек в приложениях MVC - PullRequest
3 голосов
/ 12 июня 2010

Где должен быть объявлен путь крошек (другими словами, в какой букве MVC)? До сих пор я объявлял об этом в Controllers, но недавно начал работать с CakePHP, где все сделано в Views, и это меня удивило.

Ответы [ 5 ]

4 голосов
/ 14 мая 2013

Я собираюсь выкинуть ответ здесь, потому что существует большая путаница в том, что следует и чего не следует делать с сухарями.

Модель

Модель представляет собой слой , который содержит вашу бизнес-логику , состоящую из объектов домена, картографических данных и служб. Подробнее о модели вы можете прочитать здесь .

Контроллер

Помните: толстая модель, тощие контроллеры . Ваш контроллер / метод доступен из вашего механизма маршрутизации. Как только вы окажетесь в контроллере, вы захотите получить объект модели, выполнить любую логику, требуемую в модели, вернуть результат этого в переменную вашего контроллера, а затем использовать это для отображения данных в вашем представлении.

Панировочные сухари

Как говорится, вашим сухарям нужны разные части для работы. Давайте подумаем об этом:

  • Им нужна текущая страница
  • Им нужен список страниц
  • Им (возможно) нужно добавить пользовательский "class = current"

Разбиваем их:

  • В моем фреймворке текущий контроллер также является именем страницы (контроллер входа отображается в / login). Итак, у нас уже есть текущая страница.
  • Список страниц.
    • Если ваши родительские / дочерние отношения страниц связаны напрямую с моделью данных , то в вашем контроллере вы извлекаете список страниц из модели . Поэтому используйте модель, если панировочные сухари могут быть автоматически сгенерированы .
    • Если используемый вами фреймворк допускает панировочные сухари, созданные полностью по выбору пользователя, то вы просто выбираете, что добавлять в панировочные сухари вручную. В любом случае , вы указываете свои хлебные крошки в контроллере, и если вам нужно их откуда-то достать, используйте модель.
  • Наконец, "класс = текущий". Хотя вы не должны содержать значительную «логику» в своем представлении, мелкие вещи, такие как циклы или если операторы довольно стандартны. Здесь вы должны проверить свои крошки на наличие заголовка, равного текущему имени контроллера (передаваемого в качестве переменной в представление), и добавить class=current, если найден.

Пример кода

Примечание: не проверено

/**
 * So we're in the home controller, and index action
 *
 * @route localhost/home or localhost/home/index
 * (depending on .htaccess, routing mechanism etc)
 */
class Home extends Controller
{
    public function index()
    {
        // Get current class name, so we have the current page
        $class = __CLASS__;

        // Let's say the page heirachy is tied to the model, so get pages for current method, or however you want to implement it
        $pages = $model->getPages($class);

        // So the TEMPLATE handles the breadcrumbs creation, and the controller passes it the data that it needs, retrieved from the model
        // (new Template) is PHP 5.4's constructor dereferencing, also included is some lovely method chaining
        // setBreadcrumbs() would assign variables to the view
        // Render would do just that
        (new Template)->setBreadcrumbs($currentPage, $pages)->render();
    }
}

А теперь, вид ... обратите внимание, я использую PHP 5.4, поэтому я могу использовать короткое эхо ...

<body>
    <?php foreach($breadcrumbs as $b) { ?>
        <li <?=($b['current'])?'class="current"':''?>>
            <a href="<?=$b['page']['url']?>">
                <?=$b['page']['title']?>
            </a>
        </li>
    <?php } ?>
</body>

И вот как бы я это сделал. Отчасти это зависит от личных предпочтений, но я надеюсь, что это показывает один из способов сделать это и, по крайней мере, немного полезно.

Я действительно наткнулся на этот ответ, прибегая к помощи "php mvc breadcrumbs", и выписывание моего мозга действительно помогло мне в этом разобраться. Так что спасибо!

1 голос
/ 12 июня 2010

Всякий раз, когда вы видите слова «логика» и «взгляд» вместе, вы должны начать беспокоиться.Я голосую за контроллер, потому что хлебные крошки - типичный пример логики уровня приложения, поэтому, по моему мнению, представление этого вида нарушает MVC.

0 голосов
/ 26 июня 2010
$this->Html->addCrumb('Home', '/pages/home');
$this->Html->addCrumb('Contacts', '/pages/contacts');

echo $this->Html->getCrumbs('&raquo;', 'StartText');
0 голосов
/ 12 июня 2010

IMO, «хлебная крошка» относится к набору действий контроллера, выполняемых для перехода на текущую страницу или к месту действия в иерархии сайта, в зависимости от вашей интерпретации. С этой точки зрения контроллер кажется естественным местом для создания данных для него, хотя рендеринг должен происходить в представлении. Для того, чтобы он был полностью сгенерирован в представлении, вам нужно будет либо предоставить подробности о том, какое действие контроллера вызывается представлением, либо иметь фиксированную модель представления за действие, чтобы можно было предварительно рассчитать крошку для каждого из них. Перемещение логики для вычисления хлебных крошек на само представление, по-видимому, нарушает разделение задач в MVC и может препятствовать повторному использованию представлений для различных действий, которые могут нарушить DRY>

По моему мнению, генерация данных для хлебных крошек является сквозной задачей контроллера, т. Е. У вас есть некоторый общий код, который выполняется независимо от действия, которое использует URL для создания данных хлебных крошек. Существует также некоторый общий код представления, который берет данные, предоставленные контроллером, и делает их совместимыми с проектом.

Обратите внимание, что я говорю с чисто архитектурной точки зрения. Я недостаточно знаком с CakePHP (или другими PHP-фреймворками, если на то пошло), чтобы даже судить о правильности вашего наблюдения по этому поводу. С точки зрения шаблона, поместить его в контроллер кажется правильным решением. Однако в данной реализации имеет смысл нарушать шаблон.

0 голосов
/ 12 июня 2010

Панировочные сухари должны быть в контроллере. Я использую CodeIgniter и делаю что-то вроде

$data['breadcrumb'][0] = array("title" => "Home", "alt" => "Home Page", "path" => "home/");
$data['breadcrumb'][1] = array("title" => "About", "alt" => "About Me", "path" => "home/about");

А затем в цикле просмотра просмотрите и отобразите их в виде списка.

<ul class="breadcrumbs">
foreach($breadcrumb as $b)
{
    ?>
        <li><a href="<?php echo base_url(); ?>index.php/<?php echo $b['path'];?>" alt="<?php echo $b['alt']; ?>"><?php echo $b['title']; ?></a></li>
    <?php
}
</ul>

Затем вы можете также объявить простые вещи, такие как классы, текущие страницы и т. Д. Единственным недостатком является то, что вы должны устанавливать хлебные крошки на каждой странице.

ALL логика должна быть в контроллере. Получите доступ к базам данных через модели, выполните логику в контроллере и передайте ее в представление.

Простые вещи вроде

<?php echo ($loggedin)?"Logged in as" . $user->firstname:"Not logged in";?>

может быть в поле зрения. Но вы не должны настраивать сложные схемы потока. Оставьте это контроллеру. Взгляды дешевые. Вы можете иметь полдюжины слегка разных взглядов, и никто не будет заботиться. Это не то же самое, что статический HTML, где вам нужно поддерживать полдюжины страниц.

Включите в представления общие элементы (такие как верхние и нижние колонтитулы, файлы сценариев, файлы JavaScript и т. Д.), А затем разрешите им отображаться.

...