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

Источник: lred.ru

Оцените статью
новости для мужчин