Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用create回调将嵌套对象映射为复杂JSON中的可观察对象_Javascript_Knockout.js_Knockout Mapping Plugin - Fatal编程技术网

Javascript 使用create回调将嵌套对象映射为复杂JSON中的可观察对象

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

我有一个JSON格式的复杂对象。我正在使用Knockout映射,自定义
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
绑定并自动匹配新值和旧值。如果你愿意,我也可以给你看一个重构的例子。如果有帮助,请告诉我。

谢谢。我当然对你的重构很感兴趣。我更新了我认为你的想法。它是?