Часть 5. Создание динамического пользовательского интерфейса с помощью Knockout.js
Рик Андерсон
Создание динамического пользовательского интерфейса с помощью Knockout.js
В этом разделе мы будем использовать Knockout.js для добавления функциональных возможностей в представление Администратор.
Knockout.js — это библиотека JavaScript, которая упрощает привязку элементов управления HTML к данным. Knockout.js использует шаблон MVVM.
- Модель — это представление данных на стороне сервера в бизнес-области (в нашем случае это продукты и заказы).
- Представление представляет собой слой представления (HTML).
- Модель представления — это объект JavaScript, содержащий данные модели. Модель представления — это абстракция кода пользовательского интерфейса. Он не знает представления HTML. Вместо этого он представляет абстрактные признаки представления, такие как "список элементов".
Представление привязано к модели представления. Обновления в модель представления автоматически отражаются в представлении. Модель представления также получает события из представления, такие как нажатие кнопки, и выполняет операции с моделью, такие как создание заказа.
Схема, показывающая взаимодействие между данными H T M L, моделью представления, j son и контроллером Web A P I. Поле данных H T M L имеет метку представления. Привязка данных с двойной стрелкой связывает поле данных H T M L с полем модели представления. Двойная стрелка с меткой H T TP requests and j son model from server связывает модель представления с контроллером Web A P I.
Сначала мы определим модель представления. После этого мы привяжем разметку HTML к модели представления.
Добавьте следующий раздел Razor в файл Администратор.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>
Запустите приложение, войдите в систему с учетной записью администратора и щелкните ссылку "Администратор". Вы увидите список продуктов и сможете создавать, обновлять или удалять продукты.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по