当我从中选择的列表是从另一个对象生成时,我试图填充一个对象的observable属性。 select的选项是$root.Rider
的属性,而所选的选项是$root
的属性。
如果我在select标记的绑定中使用value: selectedContract
(如示例所示),则选择一个选项会更改selectedContract
,但在加载时不会选择预设的selectContract
。< / p>
如果我将值更改为value: payment_contract().option_value
并添加optionsValue:'option_value'
,则会在加载时填充预设,但从选项列表中进行选择时,selectContract
不会更新。
代码:
$(function () {
ko.applyBindings(new ViewModel());
});
var ViewModel = function () {
var self = this;
self.selectedContract = ko.observable();
self.rider = new Rider({
id: 11
});
contract = new Contract({
terms: 'Terms 2',
account_id: '2',
account_name: 'Account 2'
});
self.selectedContract(contract)
};
//Rider
function Rider(data) { //charge options and prepaid options are arrays of contract objects
var self = this;
self.id = data.id;
self.contract_options = ko.observableArray();
//populate contract_options for demo
var contract = new Contract({
terms: 'charge',
account_id: '1',
account_name: 'Account 1'
});
self.contract_options.push(contract);
contract = new Contract({
terms: 'charge',
account_id: '2',
account_name: 'Account 2'
});
self.contract_options.push(contract);
contract = new Contract({
terms: 'charge',
account_id: '3',
account_name: 'Account 3'
});
self.contract_options.push(contract);
}
function Contract(data) {
var self = this;
self.terms = data.terms;
self.contract_id = data.contract_id;
self.account_id = data.account_id;
self.account_name = ko.observable(data.account_name);
self.option_value = ko.computed(function () {
return self.account_id + '|' + self.contract_id;
});
};
<select name="contract_id_charge" data-bind="options: rider.contract_options,
value: selectedContract,
optionsText: 'account_name',
optionsCaption: 'Select Charge'
"></select>
<div data-bind="with: selectedContract">
<div>
<label>Terms:</label><span data-bind="text: terms"></span>
</div>
<div>
<label>Account Id:</label><span data-bind="text: account_id"></span>
</div>
<div>
<label>Account Name:</label><span data-bind="text: account_name"></span>
</div>
</div>
答案 0 :(得分:1)
您的问题是您在value
标记上滥用了<select>
数据绑定。
使用<select>
标记,options
绑定指定选项列表,value
数据绑定应指定一个observable来保存当前所选选项的值。
相反,你有:value: payment_contract().option_value
,这是一个只读的计算;而不是一个观察到持有所选合同。如果您指定value: payment_contract
,则所选合同将根据需要存储在Ride的payment_contract
可观察数据中。
此外,optionValue
绑定为给定选项指定应在value
绑定指定的observable中存储的值。你正在使用一些基于account_id和contract_id的字符串;但是你似乎更有可能只想存储对整个Contract对象的引用;而不是字符串表示,因此可能会省略绑定。
以下`标签似乎有效:
<select name="contract_id_charge"
data-bind="options: rider().charge_options(),
value: payment_contract,
optionsText: 'account_name',
optionsCaption: 'Select Charge'
">
</select>
答案 1 :(得分:0)
考虑到你提出这个问题有多复杂,我尽力回答。而不是使用optionsValue绑定您的选择,只需使用值绑定。然后可以将其绑定到一个可观察对象,该观察对象将填充来自charge_options的选定选项。
<select name="contract_id_charge"
data-bind="options: contract_options(),
value: selectedContract,
optionsText: 'account_name',
optionsCaption: 'Select Charge'
"></select>
<div data-bind="with: selectedContract">
<div>
<label>Terms: </label><span data-bind="text: terms"></span>
</div>
<div>
<label>Account Id: </label><span data-bind="text: account_id"></span>
</div>
<div>
<label>Account Name: </label><span data-bind="text: account_name"></span>
</div>
</div>
var ViewModel = function () {
var self = this;
self.selectedContract = ko.observable();
self.contract_options = ko.observableArray();
//populate contract_options for demo
var contract = new Contract ({
terms: 'Terms 1',
account_id: '1',
account_name: 'Account 1'
});
self.contract_options.push(contract);
contract = new Contract ({
terms: 'Terms 2',
account_id: '2',
account_name: 'Account 2'
});
self.contract_options.push(contract);
contract = new Contract ({
terms: 'Terms 3',
account_id: '3',
account_name: 'Account 3'
});
self.contract_options.push(contract);
};
function Contract(data) {
var self = this;
self.terms = data.terms;
self.contract_id = data.contract_id;
self.account_id = data.account_id;
self.account_name = ko.observable(data.account_name);
self.option_value = ko.computed(function () {
return self.account_id + '|' + self.contract_id;
});
};