我是KnockoutJS的新手。 我有一个以下列方式工作的应用程序:
第四步我遇到了麻烦。我一直在阅读文档,但我无法弄清楚我应该如何获得更新的数据。
这是一个JSFiddle:https://jsfiddle.net/vrggyf45
以下是代码段中的相同代码。请参阅问题的底部,了解我尝试过的内容。
ko.components.register('firstComponent', {
viewModel: function(params) {
var self = this;
self.firstComponentValue = ko.observable(params.firstComponentValue);
},
template: '<div><pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre><input data-bind="value: firstComponentValue, valueUpdate: \'afterkeydown\'"></div>'
});
ko.components.register('secondComponent', {
viewModel: function(params) {
var self = this;
self.secondComponentValue = ko.observable(params.secondComponentValue);
},
template: '<div><pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre><input data-bind="value: secondComponentValue, valueUpdate: \'afterkeydown\'"></div>'
});
var json = '{"items":[{"componentName":"firstComponent","firstComponentValue":"somevalue"},{"componentName":"secondComponent","secondComponentValue":"someothervalue"}]}';
var data = JSON.parse(json);
var mainVM = {};
mainVM.items = ko.observableArray(
ko.utils.arrayMap(data.items,
function(item) {
return ko.observable(item);
}));
ko.applyBindings(mainVM);
$('input[type=button]').click(function() {
var updatedData = ko.dataFor(document.getElementById('main'));
//get updated json somehow?
console.log(data);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre>
<div data-bind="foreach: {data: items, as: 'item'}">
<hr>
<div data-bind="component: {name:componentName, params: item}">
</div>
</div>
<hr>
<input type="button" value="post data">
</div>
如果我有一个单一的视图模型,我可以使用ko.dataFor($("#rootElement"))
并将其发送到后端。但是我打算使用组件,它们有自己的视图模型,它们没有连接到根视图模型。我可以用jQuery找到它们并使用ko.dataFor
但它对我来说看起来像是一个大黑客。
我也可以定义所有的视图模型,包括主视图模型中的组件,但它使组件变得毫无用处。
此外,我尝试更改组件viewmodels构造函数,以便它们改变输入数据并使用observable覆盖incomming值,但它对我来说似乎也是一个黑客。
是否有像ko.components
这样的函数或能够给我所有生活视图模型的东西?
答案 0 :(得分:1)
您可以将observable传递给组件,以便它们的编辑立即反映在父对象中。 ko.mapping
对于将普通JS对象转换为可观察对象非常方便。然后当您想要数据时,ko.toJS()
它。
ko.components.register('firstComponent', {
viewModel: function(params) {
var self = this;
self.firstComponentValue = params.firstComponentValue;
},
template: '<div><pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre><input data-bind="value: firstComponentValue, valueUpdate: \'afterkeydown\'"></div>'
});
ko.components.register('secondComponent', {
viewModel: function(params) {
var self = this;
self.secondComponentValue = params.secondComponentValue;
},
template: '<div><pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre><input data-bind="value: secondComponentValue, valueUpdate: \'afterkeydown\'"></div>'
});
var json = '{"items":[{"componentName":"firstComponent","firstComponentValue":"somevalue"},{"componentName":"secondComponent","secondComponentValue":"someothervalue"}]}';
var data = JSON.parse(json);
var mainVM = {};
mainVM.items = ko.mapping.fromJS(data.items);
ko.applyBindings(mainVM);
$('input[type=button]').click(function() {
var updatedData = ko.toJS(ko.dataFor(document.getElementById('main')));
//Or, more simply: updatedData = ko.toJS(mainVM);
console.log(updatedData);
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre>
<div data-bind="foreach: {data: items, as: 'item'}">
<hr>
<div data-bind="component: {name:componentName, params: item}">
</div>
</div>
<hr>
<input type="button" value="post data">
</div>
&#13;