javascript - 无法在 knockoutJS 视图模型中映射 .json 数据
问题描述
我有这个小型 MVC 应用程序,它可以进行 .ajax 调用,以 .json 格式获取数据并以 html 格式显示响应。我是 knockoutJS 的新手,我在将 json 格式映射到模型时遇到问题。
我能够将我在 .ajax 调用时收到的 json 数据映射到一个数组(categories
)中,但是当我尝试将它添加到shoppingCart
数组时,它不会显示映射的数据。
有人可以帮助我为什么在尝试将数据添加到shoppingCart
集合时丢失数据吗?
数据库表:
Product
Id | Name | Price|
1 | Buns | 1.00
ProductTag
Id | Name | Fk_Product_Id|
1 | Baked Goods| 1
/* Fk_Product_Id - points to Product Id */
Json 格式的响应:
{
"Data": [
{
"ProductTags": [
{
"Id": 1,
"Name": "Baked Goods",
"Fk_Product_Id": 1
},
{
"Id": 2,
"Name": "Hot Dogs",
"Fk_Product_Id": 1
}
],
"Id": 1,
"Name": "Buns",
"Price": 1.00
}
],
}
.js 文件:
var categories = [];
$.ajax({
url: 'ShoppingCart/GetAllProducts',
cache: false,
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
// I had to map the data to model manually.
// Ko.mapper didn't work for me.
var parsed = JSON.parse(data);
var product = parsed.Data;
console.log(parsed);
for (var i = 0; i < product.length; i++) {
var id = product[i].Id;
var name = product[i].Name;
var price = product[i].Price;
var productTag = product[i].ProductTags;
categories.push(new Product(id, name, price,productTag));
}
}
});
function Product(id, name, price, productTags) {
var self = this;
self.id = ko.observable(id),
self.name = ko.observable(name);
self.price = ko.observable(price);
self.productTags = typeof (productTags) !== "undefined" ? productTags : [];
self.productTags = ko.observableArray(productTags);
}
function PersonViewModel() {
var self = this;
self.firstName = ko.observable("John");
self.lastName = ko.observable("Smith");
self.checkout = function () {
alert("Trying to checkout");
};
self.shoppingCart = ko.observableArray(categories);
};
//var viewModel = new PersonViewModel();
//ko.applyBindings(viewModel);
var viewModel = new PersonViewModel();
ko.applyBindings(viewModel, document.getElementById('shoppingCart'));
html:
<div id="shoppingCart">
<table>
<thead><tr>
<th>Item number</th>
<th>Product</th>
<th>Price</th>
<th>Tags</th>
<th>Action</th>
</tr></thead>
<tbody data-bind='foreach: shoppingCart'>
<tr>
<td data-bind='text: $index'></td>
<td data-bind='text: name'></td>
<td data-bind='text: price'></td>
<td>
<ul data-bind="foreach: productTags">
<li data-bind="text:$data">
</li>
</ul>
</td>
<td>
<button data-bind='click: $root.removeProduct'>Remove</button>
</td>
</tr>
</tbody>
</table>
</div>
解决方案
您只是在更新一个名为的局部变量categories
,而不是 viewmodel 的observableArray
属性。相反,循环Data
并推送到viewModel.shoppingCart
.
setTimeout(() => {
const response = {"Data":[{"ProductTags":[{"Id":1,"Name":"Baked Goods","Fk_Product_Id":1},{"Id":2,"Name":"Hot Dogs","Fk_Product_Id":1}],"Id":1,"Name":"Buns","Price":1.00}],}
response.Data.forEach(p => {
// push to observableArray
viewModel.shoppingCart.push(new Product(p.Id, p.Name, p.Price, p.ProductTags))
})
}, 2000)
function Product(id, name, price, productTags) {
var self = this;
self.id = ko.observable(id);
self.name = ko.observable(name);
self.price = ko.observable(price);
let tags = typeof(productTags) !== "undefined" ? productTags : [];
self.productTags = ko.observableArray(tags);
}
function PersonViewModel() {
var self = this;
self.firstName = ko.observable("John");
self.lastName = ko.observable("Smith");
self.shoppingCart = ko.observableArray([]); // initialize to empty array
};
var viewModel = new PersonViewModel();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table>
<thead>
<tr>
<th>Item number</th>
<th>Product</th>
<th>Price</th>
<th>Tags</th>
<th>Action</th>
</tr>
</thead>
<tbody data-bind='foreach: shoppingCart'>
<tr>
<td data-bind='text: $index'></td>
<td data-bind='text: name'></td>
<td data-bind='text: price'></td>
<td>
<ul data-bind="foreach: productTags">
<li data-bind="text:Name">
</li>
</ul>
</td>
<td>
<button data-bind='click: $root.removeProduct'>Remove</button>
</td>
</tr>
</tbody>
</table>
推荐阅读
- javascript - 为谷歌地图样式加载外部 JSON 文件会破坏后续地图操作
- c# - 反序列化 Newtonsoft.Json 中的自定义异常
- php - 试图获取非对象 laravel 的属性
- c# - 从数据库读取占位符文本框不起作用 Asp.net
- c - Lua C 扩展:如何在新库上设置元表
- javascript - 我想在 JS 中实现一个 LinkedList 数据结构
- xslt - 如果缺少元素,请检查 XSLT 元素和输入空间
- javascript - 基于引导字段输入预定义 Javascript 属性
- bazel - 如何找到多个 bazel 目标中包含的所有源文件?
- sql - 选择日期最小的所有行