我有两组几乎相同的代码,两者之间的唯一区别是一个元素中有一个选项 Headers 而另一个没有 . 没有optionsCaption数据的代码看似正确绑定,另一个似乎在绑定第一个元素后停止数据绑定 . 有人可以向我解释我做错了什么以及数据绑定为何如此工作?
示例1 - 不起作用,为了查看,请选择其中一个选项 - http://jsfiddle.net/749sj7w5/2/
示例2 - 正常工作 - http://jsfiddle.net/749sj7w5/3/
脚本:
var Program = function (programId, description) {
this.ProgramId = programId;
this.Description = description;
};
var myViewModel = function () {
var self = this;
self.program = ko.observable();
self.programId = ko.observable(-1);
self.availablePrograms = ko.observableArray([
new Program(1, "Program One"),
new Program(2, "Program Two"),
new Program(3, "Program Three")]);
self.programId.subscribe(function (newValue) {
self.program(self.availablePrograms()[newValue - 1]);
});
};
不工作的HTML:
<div>
<select data-bind="options: availablePrograms, optionsText: 'Description', optionsValue: 'ProgramId', value: programId, optionsCaption: 'Select a Program'"></select>
</div>
<div>
<input type="text" data-bind="value: program().Description" />
<input type="text" data-bind="value: program().Description" />
<input type="text" data-bind="value: program().ProgramId" />
</div>
工作html:
<div>
<select data-bind="options: availablePrograms, optionsText: 'Description', optionsValue: 'ProgramId', value: programId"></select>
</div>
<div>
<input type="text" data-bind="value: program().Description" />
<input type="text" data-bind="value: program().Description" />
<input type="text" data-bind="value: program().ProgramId" />
</div>
谢谢
3 回答
如果使用
optionsCaption
,则需要防御null
值,因为program()
将为undefined
,直到选择了某些内容 . 您可以执行以下操作:演示小提琴
这只会评估
program()
observable是否已设置 .浏览器控制台显示此错误:
发生这种情况是因为在第一种情况下(当不起作用时),当敲除执行绑定时,
programId
的值不会改变(因为指定了optionsCaption且未选择实际值) . 所以program
保持未定义,因为你没有用任何值初始化它(self.program = ko.observable();
) .在第二种情况下(工作时),在绑定过程中,knockout更新
programId
(设置select的默认值),因此您的订阅会触发:因此更新
program
并正确填充值 .Edit:
出现了另一个问题
当knockout绑定第一个值时,抛出异常(因为未定义)并且绑定进程停止 . 但是这个第一个绑定保持"alive",其余的只是没有约束 . 只是为了清楚 - 由于绑定只执行一次,即使
program
值发生变化,其他字段也不会受到限制 . 这就是它以如此奇怪的方式表现的原因 .注意:此讨论会从评论中复制并粘贴到同一问题的其他答案,以确保在删除答案或删除评论时不会丢失 .
问题是您的输入绑定正在尝试使用
program
observable中找到的对象的属性 . 当您将 Headers 添加到选择options
绑定时,没有初始值,因此program
最终没有值(undefined
)所以一切都崩溃了 .其他人提供了一种解决问题的方法,但另一个问题仍然存在,你没有充分利用这些绑定 .
select
元素的选定值不需要是字符串或其他简单值,它可以是任何值 . 而不是绑定到补充ID并查找关联的程序,只需绑定到程序本身 .然后,如果要访问所选程序的属性,请使用
with
绑定将上下文更改为所选程序 .请注意,如果没有选定的程序,则不会显示输入 . 如果要保持可见,请在没有选定程序时使用虚拟对象 .
演示: