Как загружать партиалы, когда они зависят от бизнес-логики? - PullRequest
0 голосов
/ 31 августа 2010

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

if($someCondition) {
    include('sidebar.php');
}

Однако в шаблоне проектирования MVC логика представления должна оставаться в представлении, в то время как бизнес-логикадолжен храниться в контроллере.Если я хочу включить частичное безоговорочно, то это не проблема, так как я могу просто иметь include('sidebar.php') на мой взгляд.Тем не менее, я больше не могу делать это условно, потому что, если логика запрещена с моей точки зрения.

Я попытался несколько решений, но все они имеют проблемы.В настоящее время я использую Решение 2:

Решение 1

Создайте функцию включения в моем классе представления, которая может условно включать содержимое из моего контроллера.Таким образом, в моем контроллере у меня может быть следующая логика:

if($someCondition) {
    $this->view->include('sidebar.php');
}   
$this->view->show('index.php');

Проблемы: sidebar.php нужно будет включить в index.php в определенной точке, требующей включения метода напросмотр объекта для выполнения какого-либо анализа.

Решение 2

Переместите управление частями из представления и поместите их в контроллер:

if($someCondition) {
    $this->view->show('header.php', 'sidebar.php', 'index.php', 'footer.php');
}
else {
    $this->view->show('header.php', 'index.php', 'footer.php');
}

Проблемы: Перемещает большую часть логики представления в область контроллера.Мне кажется более естественным, чтобы представление решало, включать ли заголовок или нет.Действительно, каждый учебник по PHP MVC, который я могу найти, имеет партиалы под управлением представления, а не контроллера.

Решение 3

Дублируйте представление и измените клон, чтобы он включал боковую панель,Тогда я мог бы условно загрузить один или другой в контроллер:

if($someCondition) {
    $this->view->show('indexWithSidebar.php');
}
else {
    $this->view->show('index.php');
}

Проблемы: Дублирование кода.Подумайте, что бы произошло, если бы у меня было 2 боковые панели, которые мне нужно было условно загрузить.Тогда мне понадобится index.php, indexWithSidebar1.php, indexWithSidebar2.php, indexWithSidebar1And2.php.Это только ухудшается с каждым условием.Помните, что весь смысл использования боковой панели как частичной состоял в том, чтобы избежать ее репликации в любом случае, и этот подход, кажется, опровергает эту точку.

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

Ответы [ 2 ]

1 голос
/ 31 августа 2010

Однако в шаблоне проектирования MVC логика представления должна храниться в взгляд в то время как бизнес-логика должен храниться в контроллере.

ИМХО: с точки зрения архитектуры, я отодвигаю свою бизнес-логику дальше от контроллера. Мы используем сервисы для обработки всей бизнес-логики и репозиториев для извлечения данных. Сервисы вызывают репозитории и затем передают обратно нашу модель данных со всей бизнес-логикой, определенной для нас. Любая внешняя логика действительно является логикой пользовательского интерфейса (покажите это, скройте это), поскольку наши возвращенные данные могут (должны быть в состоянии) использоваться в любом приложении, будь то мобильное приложение, приложение Windows или веб-приложение. 1005 *

Вы можете использовать вспомогательный метод расширения для вашего элемента управления, а в модели для партиала вы можете вернуть EmptyResult (), если вы не хотите отображать боковую панель. Или, более кратко:

<% Html.RenderAction<MyController>(x => x.Sidebar({params})); %>

А потом в контроллере:

public ViewResult Sidebar({params})
        {
            SidebarModel model = new SidebarModel();

            //...get/build model

            if ({someCondition})
            {
                return View("MySidebarPartialView", model);
            }


            return new EmptyResult();

        }
1 голос
/ 31 августа 2010

Пусть ваш контроллер оценит состояние и передаст результат на ваше усмотрение.Затем представление может решить, следует ли включать частичное.

Например, контроллер может проверить, является ли переменная $foo нулевой.Он передает результат сравнения в представление через свойство модели $model->isFooed.В этом случае вид может отображать боковую панель на основе значения $model->isFooed.

...