Real World MVC - работа с формами - PullRequest
       46

Real World MVC - работа с формами

9 голосов
/ 16 сентября 2009

Я все еще несколько озадачен тем, как MVC должен работать.

Допустим, у меня есть сайт, продающий виджеты. У меня есть страница со списком /widgets/list и страница продукта /widgets/product/123.

Оба они могут использовать контроллер widget и вызывать методы list и product - пока что достаточно просто. Допустим, у меня также есть несколько других контроллеров для разных вещей.

Теперь я добавляю поле для подписки на новостную рассылку в свой заголовок, то есть на каждую страницу сайта. Как это будет работать? Я понимаю, что он должен представить /newsletter/signup

Но что произойдет, если возникнет ошибка (скажем, вы не правильно указали свой адрес электронной почты)? Он должен показать любую страницу, на которой вы были (например, /widgets/list), но контроллер newsletter должен работать. Контроллер widget не знает о контроллере newsletter, поэтому я не могу поместить туда код ... Как это должно работать?

Редактировать: Нет AJAX, пожалуйста - я могу понять это легче. Считайте, что это запасной вариант, когда JavaScript отключен.

Редактировать 2: Любые примеры или учебные пособия, охватывающие такого рода вещи, будут очень признательны

Редактировать 3: Разрешено ли представлению вызывать действие? Например, заголовок может вызвать Newsletter->index()

Ответы [ 8 ]

6 голосов
/ 16 сентября 2009

Я не понимаю, почему сообщение об ошибке в окне новостной рассылки, которое появляется на каждой странице, должно отображаться на одной странице. Если у вас есть страница, на которой публикуется другое действие - совершенно не связанное с текущим представлением (например, поиск), то нет причины отображать сообщение об ошибке на исходной странице. Покажите ли вы сообщение об успехе на той же странице? Где это будет обработано?

Сообщения об ошибках для формы информационного бюллетеня должны отображаться в представлении, посвященном информационному бюллетеню. Например, посмотрите, как это делается в Stackoverflow - зайдите в окно поиска и ничего не вводите, просто нажмите Enter. Это ошибка, так как вы не указали, что вы хотите искать. Затем Stackoverflow перенесет вас на другую страницу, которая объясняет, как работает поиск.

Теперь, почему он это сделал? Причина проста - пользователь был на какой-то странице и решил заняться деятельностью, которая не связана с текущей страницей, поэтому нет никаких причин держать их там.

1 голос
/ 17 сентября 2009

Существует хорошее ASP.net MVC учебное пособие , описывающее методы включения виджетов (повторно используемых компонентов) в среду MVC.

Основная идея состоит в том, чтобы настроить виджеты с их собственным конвейером запросов, а не объединять их в объединенный контроллер / представление, которое нарушило бы удобство обслуживания MVC.

1 голос
/ 16 сентября 2009

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

0 голосов
/ 16 сентября 2009

Как насчет добавления скрытого поля на страницу, отправляемую в контроллер / newsletter / signup с URL-адресом, куда идти после завершения работы контроллера, т.е. текущей страницы (или вы можете использовать заголовок http реферера).

Этот контроллер затем добавляет список сообщений об ошибках или сообщение об успешном завершении в список объектов, которые должны быть визуализированы представлением, перед пересылкой на контроллер, указанный в скрытом поле выше. Затем этот контроллер добавляет свой список объектов для отображения в представлении (например, список виджетов).

Затем в представлении вы можете отобразить сообщения об ошибках от контроллера новостной рассылки, если он есть.

0 голосов
/ 16 сентября 2009

Что я делаю, так это чтобы каждая форма отправляла себе сообщение. В контроллере я проверяю, установлена ​​ли переменная post; если так, я делаю проверку. Если проверка прошла успешно, я делаю перенаправление на другую страницу. Если это не удается, страница формы просто перезагружается с сообщениями об ошибках. Это облегчает и уменьшает дублирование кода. Смотрите здесь:

**in controller**:

If post variable is set:
    validate form

    if form is validated:
        redirect to new page (or whatever)
    else:
        add error messages to the $data variable of the view
    endif

endif

//$data contains whatever information you'd normally pass to the view.
//if there was a validation error, the messages are added to the $data variable
show view with $data variable

Как видите, поток всегда падает до одного оператора загрузки представления. Однако, если проверка прошла успешно, вас уносят на другую страницу.

0 голосов
/ 16 сентября 2009

Для виджетов, которые должны возвращать некоторые ошибки проверки и т. Д. - используйте частичные запросы (или субконтроллеры из MvcContrib) + AJAX.

0 голосов
/ 16 сентября 2009

Мой опыт работы с MVC более практичен и менее ", как говорится в книге", но здесь говорится:

У вас будет базовый класс контроллеров (в CakePHP, с которым я больше всего знаком - он называется AppController), который подклассируется всеми остальными контроллерами. Этот класс будет реализовывать все "глобальные" вещи, о которых вы говорите.

Практический пример:

В моем классе AppController среда определяет обратный вызов beforeFilter(), который выполняется по существу при каждой загрузке страницы. Именно здесь я проверю, была ли отправлена ​​форма регистрации, и обработаю ее соответствующим образом. Если бы регистрация потребовала какого-то дерьма, я бы добавил что-то в сеанс, указав столько же, и мое представление просто проверит наличие списка ошибок, происходящих из модели новостной рассылки, и, если они есть, покажет их.

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

0 голосов
/ 16 сентября 2009

Вы должны поместить сообщение об ошибке в какое-то глобальное место, где контроллер страницы (который включает в себя "субконтроллеры" newsletter) может его забрать.

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

...