Давайте начнем с того, где мы остановились. Загрузите исходный код предыдущей части, разархивируйте его и откройте в Visual Studio.
В прошлый раз мы получили список расписаний, поместили его в наблюдаемый массив и использовали декларативные привязки (привязка данных), чтобы связать элементы DOM с нашей моделью представления. Другими словами, мы привязываем это к таблице. Knockout затем автоматически отображает строку для каждого расписания в массиве.
Давайте перейдем к следующему шагу в нашем небольшом приложении CRUD и добавим поддержку создания новых расписаний.
Содержание
модальный
Давайте представим пользователю возможность добавить новый график. Скопируйте / вставьте следующий HTML-код чуть ниже таблицы в представлении Index.cshtml.
<div class="pull-right"> <a id="new-timesheet" class="btn btn-success" data-toggle="modal" href="#timesheet-modal">Add timesheet</a> </div>
Это отобразит следующую кнопку под правым нижним углом таблицы.
Это демонстрирует некоторые из базовых CSS Twitter Bootstrap для быстрого рендеринга круто выглядящих кнопок .
Кнопка здесь является простым якорем. Заметьте атрибуты data-toggle и href на привязке? Bootstrap магия снова работает. Атрибут data-toggle в основном говорит Bootstrap, что при нажатии кнопки отображается модальное окно с id (href) «timesheet-modal». Кнопка (data-) переключает модальное окно.
Время добавить актуальный модал. Вставьте следующий HTML-код под кнопкой.
<div class="modal hide fade" id="timesheet-modal"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h3>Timesheet</h3> </div> <form id="Timesheet" data-bind="submit: function(form) { postTimesheet(form, 'timesheet-modal') }"> <div class="modal-body"> </div> <div class="modal-footer"> <a href="#" class="btn" data-dismiss="modal">Cancel</a> <input type="submit" class="btn btn-primary" value="Save" /> </div> </form> </div>
Модальный div изначально скрыт из-за класса CSS hide. Он состоит из трех частей, а именно:
- заголовок (модальный заголовок)
- тело (модальное тело)
- нижний колонтитул
Каждая часть украшена классом Bootstrap CSS (модальный заголовок, модальное тело и т. Д.). Заголовок содержит заголовок и кнопку (X), которая позволяет пользователю закрыть модальное окно. Атрибут кнопки data-dismiss сообщает начальной загрузке, что эта кнопка закрывает модальный режим. Тело пока пустое, в то время как нижний колонтитул содержит обычную кнопку отправки и еще одну кнопку для закрытия модального окна.
Перед запуском приложения необходимо изменить еще две вещи.
Сначала добавьте следующий CSS-код в файл site.css, который находится между bootstrap.css и bootstrap-responseive.css, чтобы удалить нижнее поле в 20px, которое начальная загрузка добавляет к формам. Обратите внимание, что тело и нижний колонтитул модала обернуты в форму.
form { margin: 0; }
Эта форма также привязана к нашей модели представления.
<form id="Timesheet" data-bind="submit: function(form) { postTimesheet(form, 'timesheet-modal') }"> ... </form>
Этот атрибут указывает Knockout вызывать функцию postTimesheet модели представления при отправке формы. Добавьте эту новую функцию в модель представления.
Примечание : обратите внимание, что здесь я передал идентификатор модального параметра функции submitTimesheet (), обернув обработчик в литерал функции, который принимает необходимые параметры. Knockout предоставляет форму по умолчанию для отправки формы, я просто добавил литерал, который содержит идентификатор модального окна. Позже вы поймете, зачем нам это нужно.
postTimesheet: function (form, modalId) { }
Хорошо, модал теперь полностью настроен. Скомпилируйте и запустите. Если вы сейчас нажмете кнопку «Добавить расписание», появится модальное окно.
Пять минут работы, и у вас есть рабочее модальное окно!
Форма
Теперь мы можем добавить форму тела тела, которую пользователь может заполнить, чтобы добавить новое расписание. Создайте частичное представление с именем _Timesheet.
Визуализируйте частичное представление в теле модала.
... <div class="modal-body"> @{ Html.RenderPartial("_Timesheet", new Timesheet()); } </div> ...
Частичное представление _Timesheet использует тип расписания в качестве модели. Он отображает некоторые элементы управления вводом для имени, фамилии, месяца и свойств года.
@model MvcApplication.Models.Timesheet @Html.LabelFor(m => m.FirstName) @Html.TextBoxFor(m => m.FirstName) @Html.LabelFor(m => m.LastName) @Html.TextBoxFor(m => m.LastName) @Html.LabelFor(m => m.Month) @Html.DropDownListFor(m => m.Month, Model.Months) @Html.LabelFor(m => m.Year) @Html.TextBoxFor(m => m.Year, new { disabled="disabled" })
Примечание . Если вы посмотрите на код модели расписания, вы заметите, что я добавил несколько аннотаций данных (требуется, отображение … и т. Д.) И IEnumerable из SelectListItem за месяцы.
Теперь ваш модал должен выглядеть следующим образом:
Давайте добавим немного CSS в файл site.css, чтобы убедиться, что обязательные поля помечены красной рамкой.
select.input-validation-error, input.input-validation-error { border-color: #FF0000; border-radius: 7px; } select.input-validation-error:focus, input.input-validation-error:focus { outline: none; border-color: #FF0000; box-shadow: 0 0 10px #FF0000; }
Если вы отправите форму, не заполнив ни одного поля, вы заметите, что поля имени и фамилии будут помечены как обязательные.
Сброс формы
Закройте модальное и снова откройте его. Что ты заметил? Да, поля по-прежнему помечены как обязательные, красная рамка и все. То же самое, если вы введете некоторые данные, они останутся там в следующий раз, когда вы снова откроете модальное окно. При открытии модальных мы должны вытереть шифер; нам нужно сбросить форму.
Свяжите событие нажатия кнопки «Добавить расписание» с функцией resetForm модели представления следующим образом:
<div class="pull-right"> <a id="new-timesheet" class="btn btn-success" data-toggle="modal" href="#timesheet-modal" data-bind="click: resetForm.bind($data, 'Timesheet')"> Add timesheet</a> </div>
Мы передаем литеральный параметр в функцию resetForm, используя функцию bind , которая присоединяет конкретное значение параметра к ссылке на функцию. Здесь мы передаем идентификатор формы, которую мы хотим сбросить.
Что касается реализации функции resetForm, то это довольно просто. Просто добавьте следующую функцию в вашу модель представления.
resetForm: function (formId) { var form = $('#' + formId); form.validate().resetForm(); form.get(0).reset(); }
Используя проверку jQuery, информация о проверке формы сбрасывается и сама форма. Если вы снова откроете модальное поле, поля станут пустыми и больше не будут помечены как обязательные.
POST-он
Теперь все на месте. Форма закончена, давайте разместим данные, введенные пользователем, и создадим новое расписание. Время реализовать функцию postTimesheet модели представления, которую мы добавили ранее.
Давайте пройдем это шаг за шагом. Сначала мы проверяем, проходит ли форма необходимую проверку.
form = $(form); if (!form.valid()) return;
Затем мы извлекаем введенную информацию из формы и сериализуем ее как JSON.
var json = JSON.stringify(this._getTimesheetFromFrom(form));
_GetTimesheetsFromForm () — это «закрытый» метод в нашей модели представления, который реализован следующим образом:
_getTimesheetFromFrom: function (form) { form = $(form); var timesheet = {}; form.find('input[type!=submit],select').each(function () { timesheet[this.name] = $(this).val(); }); return timesheet; }
Он берет все входные элементы INPUT и SELECT из формы и возвращает информацию в виде объекта JSON.
{"FirstName":"Dan","LastName":"Harrington","Month":"11","Year":"2012"}
Хорошо, давайте продолжим с реализацией функции postTimesheet (). Данные формы были проверены, полезная нагрузка JSON собрана. Время отправить данные на наш контроллер API Timesheets (REST).
Легкий Peasy Lemon Squeezy. Просто выполните вызов $ .ajax и поместите данные JSON. Когда вы получаете ответ, который является недавно добавленным расписанием, сериализованным как JSON, мы помещаем его в наш наблюдаемый массив расписаний. И последнее, но не менее важное: мы используем параметр modalId, чтобы скрыть модальное окно.
var self = this; $.ajax({ url: '@Url.RouteUrl("DefaultApi", new { httproute = "", controller = "timesheets" })', type: 'POST', data: json, dataType: 'json', contentType: 'application/json; charset=utf-8', success: function (jsonObject) { self.timesheets.push(new timesheet(jsonObject)); $('#' + modalId).modal('hide'); } });
Благодаря магии Knockout наш список расписаний будет обновляться автоматически.
В предыдущем посте было показано, как реализовать READ-часть нашего приложения CRUD, в то время как эта часть демонстрировала CREATE. В третьей статье этой серии мы повторно используем многое из того, что узнали здесь, и реализуем ОБНОВЛЕНИЕ. Четвертый и последний пост обернет все с УДАЛИТЬ.
Вы можете скачать исходный код, сопровождающий эту статью, со страницы загрузки. Если у вас есть какие-либо вопросы или предложения, напишите мне по электронной почте или оставьте комментарий.