我编写了一个名为Upload
的组件,它允许用户上传文件,然后使用带有这些文件的JSON对象进行报告。在此特定实例中,Upload
组件具有来自父视图模型的参数:
<upload params="dropzoneId: 'uploadFilesDropzone', postLocation: '/create/upload', uploadedFiles: uploadedFiles"></upload>
重要性之一称为uploadedFiles
。这里的参数绑定意味着我可以在我的组件上引用params.uploadedFiles
,并在上传时将.push()
个新对象引用到它上面。传递的数据(也称为uploadedFiles
)是我父视图模型上的observableArray:
var UploadViewModel = function () {
// Files ready to be submitted to the queue.
self.uploadedFiles = ko.observableArray([]);
};
我确实可以确认在我的组件上,params.uploadedFiles
是一个observableArray,因为它有一个push方法。在组件上更改此值后,我可以console.log()
看到它实际已更改:
params.uploadedFiles.push(object);
console.log(params.uploadedFiles().length); // was 0, now returns 1
问题这个更改似乎没有反映在我的父视图模型中。 self.uploadedFiles()
不会更改,但仍会报告长度为0.
无论我在父视图模型中添加self.uploadedFiles.subscribe(function(newValue) {});
订阅。
无论我是否在更改后在我的组件上添加params.uploadedFiles.valueHasMutated()
方法。
如何从我的组件上的数组中获取更改以反映在父视图模型的数组中?
答案 0 :(得分:2)
为什么在源已经是一个时创建一个新的可观察数组?您不能指望新对象具有与另一个对象相同的引用:只需将其作为this.uploads = params.uploads
传递给组件viewModel。在您的示例的下面修剪版本中,您将看到单击“添加”按钮时两个阵列(在不同上下文中引用的相同阵列)保持同步。
ko.components.register('upload', {
viewModel: function(params) {
this.uploads = params.uploads;
this.addUpload = function() { this.uploads.push('item'); }.bind(this);
},
template: [
'<div><button type="button" data-bind="click: addUpload">Add upload</button>',
'<span data-bind="text: uploads().length + \' - \' + $root.uploads().length"></span></div>'].join('')
});
var app = {
uploads: ko.observableArray([])
};
ko.applyBindings(app);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="component: {name: 'upload', params: {uploads: uploads}}"></div>
只有在您的源数组不可观察的情况下,事情变得更复杂并且您需要手动订阅才能更新源,例如。您将在viewModel中插入以下内容:
this.uploads.subscribe(function(newValue) { params.uploads = newValue; });
此外,text
绑定中的输出不会为源更新,因为它不可观察。如果由于某种原因我无法想到你会想要2个不同的observableArrays(1个源和1个组件),你仍然可以使用上面的行,但用params.uploads(newValue)
<替换功能代码/ p>
答案 1 :(得分:1)
问题可能与此错误有关(待确认):https://github.com/knockout/knockout/issues/1863
编辑1:所以这不是一个错误。您必须打开原始参数才能访问原始的observable。在你的情况下,它将是:
params.$raw.uploadedFiles() //this would give you access to the original observableArray and from there, you can "push", "remove", etc.
问题在于,当你将一个param传递给一个组件时,它会被包装在一个计算的observable中,当你打开它时,你没有原始的observableArray。
参考:http://knockoutjs.com/documentation/component-custom-elements.html#advanced-accessing-raw-parameters
答案 2 :(得分:0)
虽然涉及Parent的Binding属性 - &gt;儿童关系 以这种方式使用绑定
如果要将数据绑定到子属性 data-bind =&#39; BindingName:ParentViewmodel.ChildViewModel.ObservableProperty&#39;
这里似乎你想要在数组中推送任何数据时对子函数进行subcibe,你可以在Length of Observable数组上编写订阅,这可以帮助你捕获你想要的事件。
这可以解决您的问题。