Javascript 使用create回调将嵌套对象映射为复杂JSON中的可观察对象
我有一个JSON格式的复杂对象。我正在使用Knockout映射,自定义Javascript 使用create回调将嵌套对象映射为复杂JSON中的可观察对象,javascript,knockout.js,knockout-mapping-plugin,Javascript,Knockout.js,Knockout Mapping Plugin,我有一个JSON格式的复杂对象。我正在使用Knockout映射,自定义create回调,并试图确保每个应该是可观察对象的对象实际上都是这样映射的 以下代码是我得到的示例: 它允许用户添加购物车项目,保存它们(作为JSON),清空购物车,然后加载保存的项目 加载部分失败:它不显示加载选项(即加载的cartItemName)。我想这与选项列表中的对象和绑定为cartItemName的对象之间的不匹配有关(请参见此),但我无法理解 代码(): var cartitemsasson=”“; var h
create
回调,并试图确保每个应该是可观察对象的对象实际上都是这样映射的
以下代码是我得到的示例:
它允许用户添加购物车项目
,保存它们(作为JSON),清空购物车,然后加载保存的项目
加载部分失败:它不显示加载选项(即加载的cartItemName
)。我想这与选项列表中的对象和绑定为cartItemName
的对象之间的不匹配有关(请参见此),但我无法理解
代码():
var cartitemsasson=”“;
var handlerVM=函数(){
var self=这个;
self.cartItems=ko.observearray([]);
自可用产品=可观测的可观测日([]);
self.language=ko.observable();
self.init=函数(){
self.initProducts();
自我语言(“英语”);
}
self.initProducts=函数(){
自助产品推送(
新产品VM(“货架”,“白色”,“棕色”),
新产品VM(“门”,“绿色”,“蓝色”,“粉色”),
新产品虚拟机(“窗口”、“红色”、“橙色”)
);
}
self.getProducts=函数(){
返回自备产品;
}
self.getProductName=函数(产品){
if(产品){
返回self.language()=“英语”?
product.productName().english:product.productName().french;
}
}
self.getProductValue=函数(selectedProduct){
//如果不是标题
如果(所选产品){
var matched=ko.utils.arrayFirst(self.availableProducts(),函数(产品){
返回product.productName().english==selectedProduct.productName().english;
});
返回匹配;
}
}
self.getProductColor=功能(selectedProduct){
selectedProduct=selectedProduct();
如果(所选产品){
返回selectedProduct.AvailableColor();
}
}
self.addCartItem=函数(){
self.cartItems.push(new cartItemVM());
}
self.emptyCart=函数(){
自备物品([]);
}
self.saveCart=函数(){
cartItemsAsJson=ko.toJSON(self.cartItems);
log(cartItemsAsJson);
}
self.loadCart=函数(){
var loadedCartItems=ko.mapping.fromJSON(cartItemsAsJson{
创建:函数(选项){
返回新的cartItemVM(options.data);
}
});
self.cartItems(loadedCartItems());
}
}
var productVM=函数(名称、可用颜色、数据){
var self=这个;
self.productName=ko.observable({english:name,french:name+“eux”});
self.availablecolors=ko.observearray(availablecolors);
}
var cartItemVM=函数(数据){
var self=这个;
self.cartItemName=数据?
ko.observable(ko.mapping.fromJS(data.cartimeName)):
ko.可观察的();
self.cartitemcolor=数据?
ko.可观察(数据颜色):
ko.可观察的();
}
var handler=new handlerVM();
handler.init();
ko.应用绑定(处理程序)代码>
在从ViewModel->plain object->ViewModel
的转换过程中,您失去了购物车中的产品与handlerVM
中的产品之间的关系
一种常见的解决方案是,在加载普通对象时,手动搜索现有的viewmodels,然后引用它们。即:
- 我们从普通对象创建一个新的
cartItemVM
- 在其
cartItemName
中,有一个对象在handlerVM
中不存在
- 我们在
handlerVM
中查找与此对象相似的产品,并用我们找到的对象替换该对象
在代码中的loadCart
内,在设置新的viewmodels之前:
loadedCartItems().forEach(
ci => {
// Find out which product we have:
const newProduct = ci.cartItemName().productName;
const linkedProduct = self.availableProducts()
.find(p => p.productName().english === newProduct.english());
// Replace the newProduct by the one that is in `handlerVM`
ci.cartItemName(linkedProduct)
}
)
小提琴:
正如你所看到的,平等比较有点丑陋。我们查找英文
产品名称并使用它来确定匹配项。你也可以看到什么是可观察到的和什么不是有区别
我的建议是为您的产品使用唯一的id
属性,并开始使用这些属性。您可以创建一个更简单的选项value
绑定并自动匹配新值和旧值。如果你愿意,我也可以给你看一个重构的例子。如果有帮助,请告诉我。谢谢。我当然对你的重构很感兴趣。我更新了我认为你的想法。它是?