I've written a component called Upload
which allows users to upload files and then report back with a JSON object with these files. In this particular instance, the Upload
component has a parameter which comes from a parent view model:
<upload params="dropzoneId: 'uploadFilesDropzone', postLocation: '/create/upload', uploadedFiles: uploadedFiles"></upload>
The one of importance is called uploadedFiles
. The parameter binding here means I can reference params.uploadedFiles
on my component and .push()
new objects onto it as they get uploaded. The data being passed, also called uploadedFiles
, is an observableArray on my parent view model:
var UploadViewModel = function () {
// Files ready to be submitted to the queue.
self.uploadedFiles = ko.observableArray([]);
};
I can indeed confirm that on my component, params.uploadedFiles
is an observableArray, as it has a push method. After altering this value on the component, I can console.log()
it to see that it has actually changed:
params.uploadedFiles.push(object);
console.log(params.uploadedFiles().length); // was 0, now returns 1
The problem is that this change does not seem to be reflected on my parent viewmodel. self.uploadedFiles()
does not change and still reports a length of 0.
No matter if I add a self.uploadedFiles.subscribe(function(newValue) {});
subscription in my parent viewmodel.
No matter if I also add a params.uploadedFiles.valueHasMutated()
method onto my component after the change.
How can I get the changes from my array on my component to be reflected in the array on my parent view model?
Why do you create a new observable array when the source already is one? You can't expect a new object to have the same reference as another one: simply pass it to your component viewModel as
this.uploads = params.uploads
. In the below trimmed-down version of your example, you'll see upon clicking the Add button that both arrays (well the same array referenced in different contexts) stay in sync.It is only in case your source array is not observable that things get a little more complicated and you need to have a manual subscription to update the source, eg. you would insert the following in the viewModel:
Additionally the output in the
text
binding would not be updated for the source because it is not observable. If for some reason that I cannot conceive of you would want to have 2 different observableArrays (1 source & 1 component), you should still be able to do with the line above, but replace the function code withparams.uploads(newValue)