ASP.NET MVC: И снова про форму обратной связи или куда еще втыкнуть Knockout
Создание и подготовка проекта
У меня студия Visual Studio 2012 Ultimate с лицензией подписчика (не плохо да?), но вы можете воспользоваться и бесплатной версией (VS 2012 Express). Создаю новый проект ASP.NET MVC4. Сразу же, чтобы не терять время запускаю команду обновления всех nuget-пакетов (выполняю команду в Package Manager Console):
PM> Install-Package
… {много букв касаемо обновления пакетов} …
Теперь поставлю несколько дополнительных пакетов, конечно же nuget-пакетов:
PM> Install-Package knockoutjs
'knockoutjs 2.2.0' already installed.
FeedbackWithKo already has a reference to 'knockoutjs 2.2.0'.
PM> Install-Package jssite
Successfully installed 'JsSite 0.2.2'.
Successfully added 'JsSite 0.2.2' to FeedbackWithKo.
PM> Install-Package knockout.Validation
Attempting to resolve dependency 'knockoutjs (≥ 2.0.0)'.
Successfully installed 'Knockout.Validation 1.0.1'.
Successfully added 'Knockout.Validation 1.0.1' to FeedbackWithKo.
PM> Install-Package MvcTools.Mvc4
Attempting to resolve dependency 'XmlExport (≥ 0.2.1)'.
Successfully installed 'XmlExport 0.2.2'.
Successfully installed 'MvcTools.Mvc4 0.3.5'.
Successfully added 'XmlExport 0.2.2' to FeedbackWithKo.
Successfully added 'MvcTools.Mvc4 0.3.5' to FeedbackWithKo.
PM>
Раскидаю всё по папкам, для удобства, привычка, для красоты (нужное подчеркнуть). Принцип простой, мухи и котлеты отдельно:
Обратите внимание, что App в папке Scripts появится как результат установки пакета JsSite. Далее следует “прибраться” в шаблоне. Для начала удаляю _Layout.cshtml и вместо него в файле _ViewStart.cshtml ставлю использование _LayoutExtended.cshtml:
1: @{
2: Layout = "~/Views/Shared/_LayoutExtended.cshtml";
3: }
В самом шаблоне _LayoutExtended.cshtml добавлю еще одну закладку:
1: <ulid="menu">
2: <<li>@Html.ActionLink("Home", "Index", "Home")li>
3: <<li>@Html.ActionLink("About", "About", "Home")li>
4: <<li>@Html.ActionLink("Contact", "Contact", "Home")li>
5: <<li>@Html.ActionLink("Feedback", "Feedback", "Home")li>
6: ul>
В строке 5 можете наблюдать добавленный пункт меню. А в контроллере HomeController соответственно, нужен метод Feedback:
1: public ActionResult Feedback() {
2: return View();
3: }
К методу полагается еще и представление Feedback.cshtml. Я его тоже создал, но пока оставил его пустым.
А еще я сразу добавил загрузку Bundle для Knockout внизу странице (сразу после регистрации jquery):
1: @Scripts.Render("~/bundles/jquery")
2: @Scripts.Render("~/bundles/ko")
3: @RenderSection("scripts", required: false)
Создание самого пакета сжатия и минимизации в следующей части.
Разберемся с Bundle
В папке App_Start есть файл BundleConfig.cs, в котором уже есть пакеты (bundles), я добавил еще для knockout и, таким образом, вот полный файл:
1: publicclass BundleConfig {
2: // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
3: publicstaticvoid RegisterBundles(BundleCollection bundles) {
4: bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
5: "~/Scripts/lib/jquery-{version}.js"));
6:
7: bundles.Add(new ScriptBundle("~/bundles/ko").Include(
8: "~/Scripts/lib/knockout-{version}.js",
9: "~/Scripts/lib/knockout.validation.js"));
10:
11: bundles.Add(new ScriptBundle("~/bundles/site").Include(
12: "~/Scripts/app/site.core.js",
13: "~/Scripts/app/site.services.js",
14: "~/Scripts/app/site.controls.js",
15: "~/Scripts/app/site.bindingHandlers.js"));
16:
17: bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
18: "~/Scripts/lib/jquery-ui-{version}.js"));
19:
20: bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
21: "~/Scripts/lib/jquery.unobtrusive*",
22: "~/Scripts/lib/jquery.validate*"));
23:
24: bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
25: "~/Scripts/lib/modernizr-*"));
26:
27: bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
28:
29: bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
30: "~/Content/themes/base/jquery.ui.core.css",
31: "~/Content/themes/base/jquery.ui.resizable.css",
32: "~/Content/themes/base/jquery.ui.selectable.css",
33: "~/Content/themes/base/jquery.ui.accordion.css",
34: "~/Content/themes/base/jquery.ui.autocomplete.css",
35: "~/Content/themes/base/jquery.ui.button.css",
36: "~/Content/themes/base/jquery.ui.dialog.css",
37: "~/Content/themes/base/jquery.ui.slider.css",
38: "~/Content/themes/base/jquery.ui.tabs.css",
39: "~/Content/themes/base/jquery.ui.datepicker.css",
40: "~/Content/themes/base/jquery.ui.progressbar.css",
41: "~/Content/themes/base/jquery.ui.theme.css"));
42: }
43: }
В строках с 7-15 вы можете наблюдать то, что я добавил для работы knockout и для jssite. Кажется ничего не забыл.
Начнем программировать
Для того чтобы всё получилось сначала создаем FeedbackViewModel класс, для того чтобы на было что получать на стороне сервера:
1: publicclass FeedbackViewModel {
2:
3: [Required]
4: [StringLength(100)]
5: [Display(Name = "Тема сообщения")]
6: publicstring Subject { get; set; }
7:
8: [Required]
9: [StringLength(50)]
10: [Display(Name = "Как к Вам обращаться")]
11: publicstring UserName { get; set; }
12:
13: [Required]
14: [RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "Неверный формат электронной почты")]
15: [StringLength(50)]
16: [Display(Name = "Email для обратной связи")]
17: publicstring EmailAdrress { get; set; }
18:
19: [Required]
20: [StringLength(500)]
21: [DataType(DataType.MultilineText)]
22: [Display(Name = "Текст сообщения")]
23: publicstring Message { get; set; }
24:
25: }
Теперь создаем контроллер. Я буду использовать простой контроллер, который является наследником от Controller, но вы в праве использовать и ApiController. Вот содержание файла AjaxController.cs:
1: publicclass AjaxController : Controller {
2: [HttpPost]
3: public JsonResult SendFeedback(FeedbackViewModel model) {
4: if (ModelState.IsValid) {
5: // отправляем сообщение...
6: return Json(new { result = "Сообщение отправлено" });
7: }
8: else {
9: return Json(new { error = "ошибка в заполнении формы" });
10: }
11: }
12: }
На данном этапе серверная часть завершена. Теперь займемся javascript’ами.
JavaScript не желаете?
В папке Scripts/App есть файл site.services.js, в нем примерный код для обращения к сервисам сайта. Я написал такой код сервиса:
1: ///
2:
3: ///////////////////////////////////////////////////////////////
4: // simple DataService sample
5: // автор: calabonga.net
6: ///////////////////////////////////////////////////////////////
7:
8: (function (site) {
9:
10: "use strict";
11:
12: site.services.utilits = {
13: sendFeedback: function (feedback, callback) {
14: if (callback === undefined) {thrownew Error(200, "callback is undefined");}
15: site.fw.ajaxService.postJson("SendFeedback", feedback, callback);
16: }
17: };
18: })(site);
Теперь создаю новый файл site.vm.feedback.js, в котором будет ViewModel (на javascript, естественно), для работы формы обратной связи. Приведу весь код, а потом немного прокомментирую:
1: $(function () {
2:
3: site.vm.Feedback = function () {
4: var item = this;
5: item.subject = ko.observable()
6: .extend({ required: true, maxLength: 100 });
7: item.message = ko.observable()
8: .extend({ required: true, maxLength: 500 });
9: item.emailadrress = ko.observable()
10: .extend({ required: true, maxLength: 50, email: true });
11: item.username = ko.observable()
12: .extend({ required: true, maxLength: 50 });
13: return item;
14: };
15:
16: site.vm.feedbackViewModel = function () {
17: var message = ko.observable("заполните форму"),
18: feedback = new site.vm.Feedback(),
19: isbusy = ko.observable(false),
20: issended = ko.observable(false),
21: errors = ko.validatedObservable(feedback),
22: send = function () {
23: isbusy(true);
24: var jsonData = ko.toJSON(feedback);
25: site.services.utilits.sendFeedback(jsonData, callback);
26: },
27: callback = function (json) {
28: if (!json.error) {
29: alert(json.result);
30: message(json.result);
31: issended(true);
32: } else {
33: alert(json.error);
34: message(json.error);
35: }
36: isbusy(false);
37: };
38:
39: return {
40: issended:issended,
41: isbusy:isbusy,
42: errors: errors,
43: send: send,
44: feedback: feedback,
45: message: message
46: };
47: }();
48:
49: ko.applyBindings(site.vm.feedbackViewModel);
50: });
Строки 3-14: Модель (если хотете “класс”) Feedback.
Строки 6,8,10,12: Рассширения класса Feedback, наложенные для валидации объекта на форме. Для этого используется Knockout.Validation.js.
Строки 16-42: ViewModel формы обратной связи.
Строка 17: Свойство используется для отображения сообщения с сервера о результате отправки формы.
Строка 18: Экземпляр класса Feedback.
Строка 21: Инициализируем валидатор ошибок, задав объект для валидации.
Строка 22-26: Функция отправки сообщения.
Строка 27-37: Обработка результатов отправки, полученных с сервера.
Строка 49: Привязка модели к форме (это самая магическая магия под названием knockout).
Представление формы (View)
Давайте я просто покажу саму форму. А если будут вопросы, буду рад ответить на них:
1: @{
2: ViewBag.Title = "Форма обратной связи";
3: }
4: <hgroup>
5: <h2>Форма обратной связиh2>
6: <h3data-bind="text: message">h3>
7: hgroup>
8: <divdata-bind="ifnot: isbusy, ifnot: issended">
9: <p>
10: <span>Тема сообщения:span><br/>
11: <inputtype="text"data-bind="value: feedback.subject"/><br/>
12: <br/>
13:
14: <span>Ваше имя:span><br/>
15: <inputtype="text"data-bind="value: feedback.username"/><br/>
16: <br/>
17:
18: <span>Электроящик:span><br/>
19: <inputtype="text"data-bind="value: feedback.emailadrress"/><br/>
20: <br/>
21:
22: <span>Сообщение:span><br/>
23: <textareadata-bind="value: feedback.message">textarea><br/>
24: <br/>
25:
26: <buttondata-bind="click:send, enable: errors().isValid()">отправитьbutton>
27: p>
28: <p>
29: <spandata-bind="text: JSON.stringify(ko.toJS($data), null, 2)">span>
30: p>
31: div>
32:
33: @section scripts {
34: @Scripts.Render("~/bundles/site")
35: <scriptsrc="~/Scripts/app/site.vm.feedback.js">script>
36: }
Это полный текст. Давайте отправим какую-нибудь информацию:
Нажем кнопку “отправить”, и…:
Скриншот как заключение
В как результат всей статьи:
Вот и всё. Скачать demo-проект. Пишите комментарии.
Подробнее: http://feedproxy.google.com/~r/blogmusor/~3/DftF8v8FREo/105
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-11-26 » Капитан грузового судна, или Как начать использовать Docker в своих проектах
- 2024-11-26 » Обеспечение безопасности ваших веб-приложений с помощью PHP OOP и PDO
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-15 » Перенос сайта на WordPress с одного домена на другой
- 2024-11-08 » OSPanel 6: быстрый старт
- 2024-11-08 » Как установить PhpMyAdmin в Open Server Panel
- 2024-09-30 » Как быстро запустить Laravel на Windows
- 2024-09-25 » Next.js
- 2024-09-05 » OpenAI рассказал, как запретить ChatGPT использовать содержимое сайта для обучения
- 2024-08-28 » Чек-лист: как увеличить конверсию интернет-магазина на примере спортпита
- 2024-08-01 » WebSocket
- 2024-07-26 » Интеграция с Яндекс Еда
- 2024-07-26 » Интеграция с Эквайринг
- 2024-07-26 » Интеграция с СДЕК
- 2024-07-26 » Интеграция с Битрикс-24
- 2024-07-26 » Интеграция с Travelline
- 2024-07-26 » Интеграция с Iiko
- 2024-07-26 » Интеграция с Delivery Club
- 2024-07-26 » Интеграция с CRM
- 2024-07-26 » Интеграция с 1C-Бухгалтерия
- 2024-07-24 » Что такое сторителлинг: техники и примеры
- 2024-07-17 » Ошибка 404: что это такое и как ее использовать для бизнеса
- 2024-07-03 » Размещайте прайс-листы на FarPost.ru и продавайте товары быстро и выгодно
- 2024-07-01 » Профилирование кода в PHP
- 2024-06-28 » Изучаем ABC/XYZ-анализ: что это такое и какие решения с помощью него принимают
- 2024-06-17 » Зачем вам знать потребности клиента
- 2024-06-11 » Что нового в работе Яндекс Метрики: полный обзор обновления
- 2024-06-11 » Поведенческие факторы ранжирования в Яндексе
- 2024-06-11 » Скорость загрузки сайта: почему это важно и как влияет на ранжирование
Не делай другим то, что ты хотел бы, чтобы они делали для тебя. У вас могут быть разные вкусы Шоу Джордж Бернард - (1856-1950) - английский писатель. В своем творчестве ниспровергал догматизм и предвзятость, традиционность представлений |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.