9

Я все еще несколько смущен тем, как MVC должен работать.Real World MVC - Работа с формами

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

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

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

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

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

Edit 2: Любые примеры или учебники, охватывающих такие вещи были бы оценены

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

ответ

0

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

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

0

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

Вы бы базовый класс контроллера (в CakePHP - что это то, что я больше всего знакомы - это называемый AppController), который подклассифицирован всеми другими контроллерами. Этот класс будет реализовывать все «глобальные» вещи, о которых вы говорите.

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

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

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

1

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

0

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

0

У меня есть каждое сообщение формы для себя. В контроллере я проверяю, установлена ​​ли переменная 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

Если у меня есть существующий веб-сайт с 10 контроллерами, каждый из которых имеет 5 действий, разве это не значит, что мне пришлось бы отредактировать 50 функций, если бы я добавил подписку на бюллетень в заголовок? – Greg

+0

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

6

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

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

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

+0

Хотя я могу представить, что OP хочет вернуться к исходному виду, я бы, вероятно, тоже выбрал ваш предложенный подход. –

+2

Чтобы добавить к этому: чтобы сохранить «маркер», в котором находился пользователь, вы можете либо использовать файлы cookie, либо добавить строку запроса в URL-адрес. Например: '/ newsletter/signup? Return_to = widgets/list' –

+0

+1 С моей точки зрения, это вполне нормально и приемлемо перенаправить пользователя на другой контроллер, чтобы сообщить об успехе/неудаче. –

0

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

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

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

1

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

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