You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Updating a viewModel with a computed property from propertyA and propertyA at the same time ensures that either one will be fetched from the cache and it won't get updated
function DerivedViewModel(data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
}
var mapping = {
bundlemodels: {
key: function(data) {
return ko.utils.unwrapObservable(data.id)
},
create: function(options) {
debugger
return new DerivedViewModel(options.data)
}
}
}
function ViewModel(data) {
var self = this;
// Bundle is a JS object
// Say we want to unpack the bundle data to create a list of viewmodels instead of creatng a viewmodel
data = Object.assign(data, {
'bundlemodels': self.extractFromBundle(data.bundle || {})
})
var vmData = Object.assign({
bundle: {}
}, data)
ko.mapping.fromJS(vmData, mapping, self);
}
ViewModel.prototype = {
/**
* Return an Array of data from the bundledata to track all updates in an observableArray
*/
'extractFromBundle': function(bundleData) {
return Object.values(bundleData)
},
/**
* Since the Object was created with the bundle extracted, the update flow should do the same
* The issue here is that the bundle data contains the very same data as the items that would
* be extracted from it. This triggers the alreadyMapped line inthe updateViewModel of the ko.mapping
* causing my mapped item not to be updated
*/
update: function(data) {
var self = this;
data = Object.assign(data, {
'bundlemodels': self.extractFromBundle(data.bundle || {})
})
ko.mapping.fromJS(data, self)
}
}
var viewModelData = {
bundle: {
id1: {
name: 'Amazing name',
id: 'id1'
},
id2: {
name: 'Amazing name2',
id: 'id2'
}
}
}
var updatedViewModelData = {
bundle: {
id1: {
name: 'Amazing name',
id: 'id1'
},
id2: {
name: 'Amazing namechanged',
id: 'id2'
}
}
}
var initialViewModel = new ViewModel(viewModelData)
var updatedViewModel = new ViewModel(viewModelData)
updatedViewModel.update(updatedViewModelData)
Following my explanation:
updatedViewModel.bundle and updatedViewModel.bundlemodels contain the same data. When bundle is checked for updating: this model data is cached.
When updating the bundlemodels, it retrieves the cacheddata and says it no longer has to update it.
This leaves updatedViewModel behind with only one of the two properties being properly updated
Calling the update function:
Loops over the bundle object, makes everything observable and caches all these values within the simpleobject
Loops over the bundlemodels array, checks if the objects currently exist within the cache (it does, because the same model was applied for the bundle object) and it does not update the bundlemodels
The reason for the 'computed' of the bundle object is to have an array with models that are persistent (checking on the key function). The bundle object can not be used to achieve this...
It is an issue that I'm currently facing in my code
Workaround:
The only solution for me is to skip making the bundle object observable. Specifying it within the copy array of the mapping solves my caching issue.
Other solution:
If you'd require both properties to be observable, the copy cannot be used. For that, you'd need to derive the other property from the copy of the original one (they won't reference the same instance then)
The text was updated successfully, but these errors were encountered:
Problem description
Updating a viewModel with a computed property from propertyA and propertyA at the same time ensures that either one will be fetched from the cache and it won't get updated
Following my explanation:
updatedViewModel.bundle and updatedViewModel.bundlemodels contain the same data. When bundle is checked for updating: this model data is cached.
When updating the bundlemodels, it retrieves the cacheddata and says it no longer has to update it.
This leaves updatedViewModel behind with only one of the two properties being properly updated
Calling the update function:
The reason for the 'computed' of the bundle object is to have an array with models that are persistent (checking on the key function). The bundle object can not be used to achieve this...
It is an issue that I'm currently facing in my code
Workaround:
The only solution for me is to skip making the bundle object observable. Specifying it within the copy array of the mapping solves my caching issue.
Other solution:
If you'd require both properties to be observable, the copy cannot be used. For that, you'd need to derive the other property from the copy of the original one (they won't reference the same instance then)
The text was updated successfully, but these errors were encountered: