我有一个可观察的父数组,并且在某些内容中也有子数组,如
function locationDeviceViewModel(location) {
var self = this;
self.locationId = location.locationId;
self.locationName = location.locationName;
self.isSelected = ko.observable(location.isSelected);
self.deviceList = ko.observableArray();
location.deviceList.forEach(function (currentDevice) {
self.deviceList.push(new deviceViewModel(currentDevice));
promotionsViewModel.location.totalDevice.push(new deviceViewModel(currentDevice));
});
self.isSelected.subscribe(function (checked) {
self.deviceList().forEach(function (device) {
device.isDeviceSelected(checked);
});
});
self.selectedDevices = ko.computed({
read: function () {
return self.deviceList().filter(function (item) {
return item.isDeviceSelected();
});
}
});
}
在运行时我正在使用临时数组availableDevicesOnStore,其填充如下
self.availableDevicesOnStore([]);
self.retriveDeviceInProgress(true);
self.errorFetchingDevices(false);
self.selectedStoreIndex(currentIndex);
self.locationsForMerchant()[currentIndex].deviceList().forEach(function (currentDevice) {
self.availableDevicesOnStore.push(currentDevice);
});
self.retriveDeviceInProgress(false);
我很想知道为什么我在self.availableDevicesOnStore中进行更改并反映原始数组中的更改,即self.locationsForMerchant()为什么?
答案 0 :(得分:0)
在javascript中传递对象(或数组)时,总是传递byref,这意味着即使将array1分配给array2,array2中的更改也会影响array1。由于每个属性实际上都是一个对象,所以这些问题会被淘汰放大。
这可能是一个非常令人沮丧的问题,我过去所做的,当我想通过值传递一个ko对象时,就是创建一个阴影复制方法
类似这样的事情
function shadowCopy (src) {
var ret = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
if (ko.isObservable(src[prop])) {
ret[prop] = src[prop]();
} else {
ret[prop] = src[prop];
}
}
}
return ret;
}
对于一个对象,请注意你不是一个数组。但你应该得到要点。 可能有更好的解决方案,但这是我发现在处理包含可观察对象的对象和数组时最好的解决方案
答案 1 :(得分:0)
默认情况下,ko维持参考
更改您的代码以进行深层复制
self.availableDevicesOnStore([]);
self.retriveDeviceInProgress(true);
self.errorFetchingDevices(false);
self.selectedStoreIndex(currentIndex);
self.locationsForMerchant()[currentIndex].deviceList().forEach(function (currentDevice) {
self.availableDevicesOnStore.push(ko.mapping.fromJS(ko.toJS(currentDevice));
});
self.retriveDeviceInProgress(false);
ko.toJS首先将您的对象转换为计划javascript对象,删除所有可观察的属性 那么 ko.mapping.fromJS 将映射普通的js对象 注意:这需要ko映射插件。