Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Рик Андерсон
Скачивание завершенного проекта
Создание динамического пользовательского интерфейса с помощью Knockout.js
В этом разделе мы будем использовать Knockout.js для добавления функций в представление администратора.
Knockout.js — это библиотека Javascript, которая упрощает привязку элементов управления HTML к данным. Knockout.js использует шаблон модель-представление-представление модели (MVVM).
- Модель — это серверное представление данных в бизнес-домене (в нашем случае продукты и заказы).
- Представление — это слой презентации (HTML).
- Модель представления — это объект JavaScript, содержащий данные модели. Модель представления — это абстракция кода пользовательского интерфейса. У него нет знаний о представлении HTML. Вместо этого он представляет абстрактные функции представления, такие как "список элементов".
Представление привязано к модели представления. Обновления модели представления автоматически отражаются в представлении. Модель представления также получает события из представления, такие как нажатия кнопки, и выполняет операции с моделью, например создание заказа.
Схема, демонстрирующая взаимодействие между данными HTML, моделью представления, JSON и контроллером Web API. Поле данных H T M L помечено как вид. Привязка данных с двойной стрелкой связывает поле данных H T M L с полем модели представления. Двойная стрелка с меткой HTTP-запросов и JSON-модели с сервера связывает модель представления с контроллером Web API.
Сначала мы определим модель представления. После этого мы привязываем разметку HTML к модели представления.
Добавьте следующий раздел Razor в файл Admin.cshtml:
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.1.0.js")"></script>
<script type="text/javascript">
// View-model will go here
</script>
}
Этот раздел можно добавить в любом месте файла. Когда вид отрисован, раздел отображается внизу HTML-страницы, прямо перед закрывающим тегом </body>.
Все скрипты для этой страницы будут находиться внутри тега скрипта, указанного комментарием:
<script type="text/javascript">
// View-model will go here
</script>
Сначала определите класс модели представления:
function ProductsViewModel() {
var self = this;
self.products = ko.observableArray();
}
ko.observableArray — это особый вид объекта в Нокауте, который называется наблюдаемым. Из документации по Knockout.js: наблюдаемый объект — это объект JavaScript, который может уведомлять подписчиков об изменениях, когда содержимое наблюдаемого объекта изменяется, представление автоматически обновляется для соответствия.
Чтобы заполнить products массив, выполните запрос AJAX к веб-API. Помните, что мы сохранили базовый универсальный код ресурса (URI) для API в контейнере представления (см. часть 4 руководства).
function ProductsViewModel() {
var self = this;
self.products = ko.observableArray();
// New code
var baseUri = '@ViewBag.ApiUrl';
$.getJSON(baseUri, self.products);
}
Затем добавьте функции в модель представления для создания, обновления и удаления продуктов. Эти функции передают вызовы AJAX в веб-API и используют результаты для обновления модели представления.
function ProductsViewModel() {
var self = this;
self.products = ko.observableArray();
var baseUri = '@ViewBag.ApiUrl';
// New code
self.create = function (formElement) {
// If the form data is valid, post the serialized form data to the web API.
$(formElement).validate();
if ($(formElement).valid()) {
$.post(baseUri, $(formElement).serialize(), null, "json")
.done(function (o) {
// Add the new product to the view-model.
self.products.push(o);
});
}
}
self.update = function (product) {
$.ajax({ type: "PUT", url: baseUri + '/' + product.Id, data: product });
}
self.remove = function (product) {
// First remove from the server, then from the view-model.
$.ajax({ type: "DELETE", url: baseUri + '/' + product.Id })
.done(function () { self.products.remove(product); });
}
$.getJSON(baseUri, self.products);
}
Теперь наиболее важная часть: когда DOM полностью загружен, вызовите функцию ko.applyBindings и передайте новый экземпляр ProductsViewModel:
$(document).ready(function () {
ko.applyBindings(new ProductsViewModel());
})
Метод ko.applyBindings активирует Knockout и связывает модель представления с представлением.
Теперь, когда у нас есть модель представления, мы можем создать привязки. В Knockout.jsэто можно сделать, добавив data-bind атрибуты в элементы HTML. Например, чтобы привязать список HTML к массиву, используйте привязку foreach :
<ul id="update-products" data-bind="foreach: products">
Привязка foreach выполняет итерацию по массиву и создает дочерние элементы для каждого объекта в массиве. Привязки к дочерним элементам могут ссылаться на свойства объектов массива.
Добавьте следующие привязки в список "update-products":
<ul id="update-products" data-bind="foreach: products">
<li>
<div>
<div class="item">Product ID</div> <span data-bind="text: $data.Id"></span>
</div>
<div>
<div class="item">Name</div>
<input type="text" data-bind="value: $data.Name"/>
</div>
<div>
<div class="item">Price ($)</div>
<input type="text" data-bind="value: $data.Price"/>
</div>
<div>
<div class="item">Actual Cost ($)</div>
<input type="text" data-bind="value: $data.ActualCost"/>
</div>
<div>
<input type="button" value="Update" data-bind="click: $root.update"/>
<input type="button" value="Delete Item" data-bind="click: $root.remove"/>
</div>
</li>
</ul>
Элемент <li> возникает в области привязки foreach . Это означает, что Knockout отрисовывает элемент один раз для каждого продукта в массиве products . Все привязки в элементе <li> ссылаются на этот экземпляр продукта. Например, $data.Name относится к свойству Name продукта.
Чтобы задать значения текстовых входных данных, используйте привязку value . Кнопки привязаны к функциям в представлении модели с помощью привязки click . Экземпляр продукта передается в качестве параметра для каждой функции. Дополнительные сведения см. в документации по Knockout.js с хорошими описаниями различных привязок.
Затем добавьте привязку для события отправки в форме добавления продукта:
<form id="addProduct" data-bind="submit: create">
Эта привязка вызывает create функцию в модели представления для создания нового продукта.
Ниже приведен полный код для представления администратора:
@model ProductStore.Models.Product
@{
ViewBag.Title = "Admin";
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.0.0.js")"></script>
<script type="text/javascript">
function ProductsViewModel() {
var self = this;
self.products = ko.observableArray();
var baseUri = '@ViewBag.ApiUrl';
self.create = function (formElement) {
// If valid, post the serialized form data to the web api
$(formElement).validate();
if ($(formElement).valid()) {
$.post(baseUri, $(formElement).serialize(), null, "json")
.done(function (o) { self.products.push(o); });
}
}
self.update = function (product) {
$.ajax({ type: "PUT", url: baseUri + '/' + product.Id, data: product });
}
self.remove = function (product) {
// First remove from the server, then from the UI
$.ajax({ type: "DELETE", url: baseUri + '/' + product.Id })
.done(function () { self.products.remove(product); });
}
$.getJSON(baseUri, self.products);
}
$(document).ready(function () {
ko.applyBindings(new ProductsViewModel());
})
</script>
}
<h2>Admin</h2>
<div class="content">
<div class="float-left">
<ul id="update-products" data-bind="foreach: products">
<li>
<div>
<div class="item">Product ID</div> <span data-bind="text: $data.Id"></span>
</div>
<div>
<div class="item">Name</div>
<input type="text" data-bind="value: $data.Name"/>
</div>
<div>
<div class="item">Price ($)</div>
<input type="text" data-bind="value: $data.Price"/>
</div>
<div>
<div class="item">Actual Cost ($)</div>
<input type="text" data-bind="value: $data.ActualCost"/>
</div>
<div>
<input type="button" value="Update" data-bind="click: $root.update"/>
<input type="button" value="Delete Item" data-bind="click: $root.remove"/>
</div>
</li>
</ul>
</div>
<div class="float-right">
<h2>Add New Product</h2>
<form id="addProduct" data-bind="submit: create">
@Html.ValidationSummary(true)
<fieldset>
<legend>Contact</legend>
@Html.EditorForModel()
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
</form>
</div>
</div>
Запустите приложение, войдите с помощью учетной записи администратора и щелкните ссылку "Администратор". Вы увидите список продуктов и сможете создавать, обновлять или удалять продукты.