Knockout.js如何与组件共享viewmodel observable以进行双向绑定
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Knockout.js如何与组件共享viewmodel observable以进行双向绑定相关的知识,希望对你有一定的参考价值。
在这个简化的例子中,我试图为地址创建单一的事实来源。
vm.companies()[0].address().address1
需要是一个可观察的,它与地址输入组件共享/连线。
我可能正在使用错误的设计模式来实现我想要实现的目标。具体来说,这是不起作用的部分。
<script type="text/html" id="address-template"> <!-- Address Form Template -->
<div>
<input type="text" data-bind="textInput: address1" /> <!-- should bind to company.address().address1() -->
<input type="text" data-bind="textInput: city" /> <!-- should bind to company.address().city() -->
</div>
</script>
在地址输入组件中键入address1 / city文本应更新页面上显示的address1 / city文本。提前致谢!
<!DOCTYPE html>
<html>
<head>
<title>Component Observable</title>
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-debug.js"></script>
<script>
var vm = '';
var companyList = [
{ name: 'Microsoft', type: 'Software', address: { address1: '42 Binary Ave', city: 'Seattle' } },
{ name: 'Amazon', type: 'Retail', address: { address1: '1337 Compute Street', city: 'Atlanta' } }
];
var addressVm = function (params) {
this.address1 = ko.observable(params.address().address1);
this.city = ko.observable(params.address().city);
};
var companyVm = function (params) {
this.name = ko.observable(params.name);
this.type = ko.observable(params.type);
this.address = ko.observable(params.address);
};
ko.components.register('address-input', {
viewModel: addressVm,
template: { element: 'address-template' }
});
window.onload = () => {
function viewModel() {
this.init = (Vm) => {
$.each(companyList, (i, company) => {
cvm = new companyVm(company);
this.companies.push(cvm);
});
};
this.companies = ko.observableArray([]);
this.init(this);
}
vm = new viewModel();
ko.applyBindings(vm);
};
</script>
</head>
<body>
<script type="text/html" id="address-template"> <!-- Address Form Template -->
<div>
<input type="text" data-bind="textInput: address1" /> <!-- should bind to company.address().address1() -->
<input type="text" data-bind="textInput: city" /> <!-- should bind to company.address().city() -->
</div>
</script>
<div data-bind="foreach: { data: companies, as: 'company' }">
<div>
<input type="text" data-bind="textInput: company.name" />
<div data-bind="text: company.name"></div>
<input type="text" data-bind="textInput: company.type" />
<div data-bind="text: company.type"></div>
<div data-bind="text: company.address().address1"></div>
<div data-bind="text: company.address().city"></div>
<address-input params="address: company.address()"></address-input>
</div>
<hr />
</div>
</body>
</html>
答案
对地址和公司视图模型进行以下更改可实现所需的结果。
从addressVm
视图模型中删除Observable声明,并将属性放在companyVm
中。
var addressVm = function (params) {
this.address1 = params.address().address1;
this.city = params.address().city;
};
var companyVm = function (params) {
this.name = ko.observable(params.name);
this.type = ko.observable(params.type);
this.address = ko.observable({
address1: ko.observable(params.address.address1),
city: ko.observable(params.address.city)
});
};
现在,组件绑定到与其父级相同的可观察对象。在地址组件中键入文本会更新组件外部显示的文本。
以上是关于Knockout.js如何与组件共享viewmodel observable以进行双向绑定的主要内容,如果未能解决你的问题,请参考以下文章
如何将 knockout.js 与 ASP.NET MVC ViewModels 一起使用?