Knockout.js 是否有公认的处理惯例;“是或否”;下拉列表中的;“未设置”;在用户输入之前?
我认为这是一种常见的情况,我想知道是否有一个公认的惯例,如何在淘汰赛中处理这个问题。您有一个“是-否”下拉列表(或一对单选按钮),它的默认值是一个空白项(对于单选按钮,或两者都未选中)。用户必须做出选择才能继续 这并不完全映射到模型中的布尔值,因为实际上有三个可能的值。True、false和无用户选择。在C语言中,你可以考虑使用布尔值,而在java中你可以使用。在这两种情况下,“null”都不能表示用户选择 JavaScript没有可空值,但由于它不强制变量类型,因此可以采用一种约定,即特定变量可以为null、true或false,并以与C#中的可空布尔值或java.lang.boolean类似的方式使用它 首先,是绑定到布尔值的问题。Knockout希望所有绑定值在默认情况下都是字符串类型。本文对此进行了讨论,RP Niemeyer提供的解决方案是使用自定义绑定,如下所示:() 所以我用它作为我的出发点,我提出了这个定制绑定。它似乎起作用了。我对社区对这种方法的反馈很感兴趣。签出该文件以自己进行实验。这有什么缺点和/或可伸缩性问题吗Knockout.js 是否有公认的处理惯例;“是或否”;下拉列表中的;“未设置”;在用户输入之前?,knockout.js,javascript,knockout-2.0,Knockout.js,Javascript,Knockout 2.0,我认为这是一种常见的情况,我想知道是否有一个公认的惯例,如何在淘汰赛中处理这个问题。您有一个“是-否”下拉列表(或一对单选按钮),它的默认值是一个空白项(对于单选按钮,或两者都未选中)。用户必须做出选择才能继续 这并不完全映射到模型中的布尔值,因为实际上有三个可能的值。True、false和无用户选择。在C语言中,你可以考虑使用布尔值,而在java中你可以使用。在这两种情况下,“null”都不能表示用户选择 JavaScript没有可空值,但由于它不强制变量类型,因此可以采用一种约定,即特定变量
ko.bindingHandlers.nullableBooleanValue = {
init: function(element, valueAccessor, allBindingsAccessor) {
var observable = valueAccessor(),
interceptor = ko.computed({
read: function() {
console.log(observable());
console.log(typeof(observable()));
var result = null;
if(observable() === true){
result = "true";
} else if(observable() === false){
result = "false";
} else { // Default is null, which represents no user selection
result = "null";
}
console.log("transforming on read:")
console.log(typeof(observable()));
console.log(observable());
console.log(typeof(result));
console.log(result);
return result;
},
write: function(newValue) {
var result = null;
if(newValue === "true"){
result = true;
} else if(newValue === "false"){
result = false;
} else { // Default is null, which represents no user selection
result = null;
}
console.log("transforming on write:")
console.log(typeof(newValue));
console.log(newValue);
console.log(typeof(result));
console.log(result);
observable(result);
}
});
ko.applyBindingsToNode(element, { value: interceptor });
}
};
var model = {
state: ko.observable(null)
};
ko.applyBindings(model);
好的,extender方法并没有按照我希望的方式工作,所以我放弃了它(如果您好奇的话,它仍在编辑历史记录中)。我修改了你的绑定,让它把选项放在上面,这样你就不用在HTML中指定它们了。您还可以选择指定“Null”选项文本(可以展开此选项以允许设置每个标签) 此方法允许您将可观察对象视为标准的可空布尔值。以下是HTML(注意,
nullLabel
是完全可选的):
这是。你能解释一下这条线是干什么用的吗<代码>拦截器.options=[选项| |“”,“是”,“否”]代码>如果我正确阅读了您的示例,interceptor.options将设置为空字符串“”。但我看不出它在哪里或如何被使用。谢谢谢谢你的澄清。然而,有些事情并不正常。我不确定我是否做错了什么,但当我尝试为ViewModel字段“answer”赋值时,更改不会传播回select元素@该死的,我没试过。它不起作用,因为布尔值在下拉列表的选项中没有显示对应项。我正在做一个更新,可能要到明天。谢谢你的反馈和探索一些不同的选择,泰尔修斯!
ko.bindingHandlers.nullableBooleanValue = {
init: function(element, valueAccessor, allBindingsAccessor) {
var observable = valueAccessor(),
interceptor = ko.computed({
read: function() {
console.log(observable());
console.log(typeof(observable()));
var result = null;
if(observable() === true){
result = "true";
} else if(observable() === false){
result = "false";
} else { // Default is null, which represents no user selection
result = "null";
}
console.log("transforming on read:")
console.log(typeof(observable()));
console.log(observable());
console.log(typeof(result));
console.log(result);
return result;
},
write: function(newValue) {
var result = null;
if(newValue === "true"){
result = true;
} else if(newValue === "false"){
result = false;
} else { // Default is null, which represents no user selection
result = null;
}
console.log("transforming on write:")
console.log(typeof(newValue));
console.log(newValue);
console.log(typeof(result));
console.log(result);
observable(result);
}
});
ko.applyBindingsToNode(element, { value: interceptor });
}
};
var model = {
state: ko.observable(null)
};
ko.applyBindings(model);
<select data-bind="yesNoNull: answer, nullLabel: 'Null' "></select>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
ko.bindingHandlers.yesNoNull = {
init: function(element, valueAccessor, allBindingsAccessor) {
var target = valueAccessor();
var nullLabel = allBindingsAccessor().nullLabel || "";
var options = function() { return [ nullLabel, "Yes", "No"]; };
ko.bindingHandlers.options.update(element, options, allBindingsAccessor);
var observable = valueAccessor(),
interceptor = ko.computed({
read: function() {
var result = nullLabel;
if(observable() === true){
result = "Yes";
} else if(observable() === false){
result = "No";
}
return result;
},
write: function(newValue) {
var result = null;
if(newValue === "Yes"){
result = true;
} else if(newValue === "No"){
result = false;
}
observable(result);
}
});
ko.applyBindingsToNode(element, { value: interceptor });
}
};