将真/假绑定到挖空 JS 中的单选按钮
Binding true / false to radio buttons in Knockout JS
在我的视图模型中,我有一个具有真或假值的IsMale值。
在我的UI中,我希望将其绑定到以下单选按钮:
<label>Male
<input type="radio" name="IsMale" value="true" data-bind="checked:IsMale"/>
</label>
<label>Female
<input type="radio" name="IsMale" value="false" data-bind="checked:IsMale"/>
</label>
我认为问题是checked
期望一个字符串"真"/"假"。所以我的问题是,我怎样才能获得这个 2 向绑定/这个 UI 和模型?
这是一个旧线程,但我遇到了同样的问题,并发现了一个更好的解决方案,在这个问题得到正式回答后,该解决方案可能被添加到淘汰赛中,所以我把它留给有同样问题的人。
目前不需要扩展器、自定义绑定处理程序或计算。只需提供一个"checkedValue"选项,它将使用它而不是html 'value'属性,并且您可以传递任何javascript值。
<input type="radio" name="a" data-bind="checked:IsChecked, checkedValue: true"/>
<input type="radio" name="a" data-bind="checked:IsChecked, checkedValue: false"/>
或:
<input type="radio" name="b" data-bind="checked:Quantity, checkedValue: 1"/>
<input type="radio" name="b" data-bind="checked:Quantity, checkedValue: 2"/>
<input type="radio" name="b" data-bind="checked:Quantity, checkedValue: 3"/>
一种选择是使用可写的计算可观察量。
在这种情况下,我认为一个不错的选择是使可写计算可观察的可观察量成为可观察IsMale
的"子可观察量"。 您的视图模型如下所示:
var ViewModel = function() {
this.IsMale = ko.observable(true);
this.IsMale.ForEditing = ko.computed({
read: function() {
return this.IsMale().toString();
},
write: function(newValue) {
this.IsMale(newValue === "true");
},
owner: this
});
};
您可以将其绑定到您的 UI 中,如下所示:
<label>Male
<input type="radio" name="IsMale" value="true" data-bind="checked:IsMale.ForEditing"/>
</label>
<label>Female
<input type="radio" name="IsMale" value="false" data-bind="checked:IsMale.ForEditing"/>
</label>
样品:http://jsfiddle.net/rniemeyer/Pjdse/
我有用:
http://jsfiddle.net/zrBuL/291/
<label>Male
<input type="radio" name="IsMale" value="1" data-bind="checked:IsMale"/>
</label>
<label>Female
<input type="radio" name="IsMale" value="0" data-bind="checked:IsMale"/>
</label>
ko.bindingHandlers['radiobuttonyesno'] = {
'init': function (element, valueAccessor, allBindingsAccessor) {
var stateHandler = function (property, allBindingsAccessor, key, value, checkIfDifferent) {
if (!property || !ko.isObservable(property)) {
var propWriters = allBindingsAccessor()['_ko_property_writers'];
if (propWriters && propWriters[key])
propWriters[key](value);
} else if (ko.isWriteableObservable(property) && (!checkIfDifferent || property.peek() !== value)) {
property(value);
}
};
var updateHandler = function () {
var valueToWrite;
if ((element.type == "radio") && (element.checked)) {
valueToWrite = element.value;
} else {
return; // "radiobuttonyesno" binding only responds to selected radio buttons
}
valueToWrite = (valueToWrite === "True") ? true : false;
var modelValue = valueAccessor(), unwrappedValue = ko.utils.unwrapObservable(modelValue); //can be true of false
stateHandler(modelValue, allBindingsAccessor, 'checked', valueToWrite, true);
};
ko.utils.registerEventHandler(element, "click", updateHandler);
// IE 6 won't allow radio buttons to be selected unless they have a name
if ((element.type == "radio") && !element.name)
ko.bindingHandlers['uniqueName']['init'](element, function () { return true });
},
'update': function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
value = value ? "True" : "False";
if (element.type == "radio") {
element.checked = (element.value == value);
}
}
};
使用此活页夹而不是创建愚蠢的 ko 计算可观察量。
例:
<label>Male
<input type="radio" name="IsMale" value="True" data-bind="radiobuttonyesno:IsMale"/>
</label>
<label>Female
<input type="radio" name="IsMale" value="False" data-bind="radiobuttonyesno:IsMale"/>
</label>
一旦您确定单选按钮的初始匹配项只想匹配字符串并希望将值设置为字符串,只需将初始值转换为字符串即可。我不得不用 Int 值来对抗这个问题。
设置可观察量后,将值转换为字符串,KO将从那里发挥其魔力。如果要映射单个行,请在这些行中进行转换。
在示例代码中,我使用 Json 在单个命令中映射整个模型。然后让 Razor 在引号之间插入值以进行转换。
script type="text/javascript">
KoSetup.ViewModel = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)));
KoSetup.ViewModel.ManifestEntered("@Model.ManifestEntered"); //Bool
KoSetup.ViewModel.OrderStatusID("@Model.OrderStatusID"); //Int
</script>
在开发过程中,我在网页底部使用"将其全部转储到屏幕"。
<h4>Debug</h4>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
以下是数据值,之前
"OrderStatusID": 6,
"ManifestEntered": true,
并且,之后
"OrderStatusID": "6",
"ManifestEntered": "True",
在我的项目中,我不需要转换布尔值,因为我可以使用一个没有同样挫败感的复选框。
为什么不简单地 true 和 false 而不是 1 和 0?
<label>Male
<input type="radio" name="IsMale" value="true" data-bind="checked:IsMale"/>
</label>
<label>Female
<input type="radio" name="IsMale" value="false" data-bind="checked:IsMale"/>
</label>
您还可以使用扩展器,以便轻松地将它们重用于更多可观察量:
ko.extenders.boolForEditing = function (target, allowNull) {
var result = ko.computed({
read: function () {
var current = target();
var newValue = null;
if (current === undefined || current === null || current === '') {
if (!allowNull) {
newValue = 'false';
}
} else {
newValue = current ? 'true' : 'false';
}
return newValue;
},
write: function (newValue) {
var current = target();
var valueToWrite = null;
if (newValue === undefined || newValue === null || newValue === '') {
if (!allowNull) {
valueToWrite = false;
}
} else {
valueToWrite = newValue === 'true';
}
// only write if it changed
if (valueToWrite !== current) {
target(valueToWrite);
} else {
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({
notify: 'always'
});
result(target());
return result;
};
然后像这样使用它:
this.IsMale.forEditing = this.IsMale.extend({boolForEditing: true});
提供给boolForEditing
的参数指示该值是否可以为 null。
请参阅 http://jsfiddle.net/G8qs9/1/
在对 3.0 之前的旧版本淘汰赛进行了大量研究之后,可能有两个最佳选择
创建一个挖空扩展器,例如
ko.extenders["booleanValue"] = function (target) {
target.formattedValue = ko.computed({
read: function () {
if (target() === true) return "True";
else if (target() === false) return "False";
},
write: function (newValue) {
if (newValue) {
if (newValue === "False") target(false);
else if (newValue === "True") target(true);
}
}
});
target.formattedValue(target());
return target;
};
若要在模型上使用扩展器,请执行如下所示的操作:
function Order() {
this.wantsFries= ko.observable(false).extend({ booleanValue: null });
}
<span>Do you want fries with that?</span>
<label>
<input type="radio" name="question" value="True"
data-bind="value: wantsFries.formattedValue" /> Yes
</label>
<label>
<input type="radio" name="question" value="False"
data-bind="value: wantsFries.formattedValue" /> No
</label>
来源:http://www.timlabonne.com/2013/02/building-a-knockout-js-extender-for-boolean-values/
- vue-js-单选按钮won't默认情况下使用v-model属性进行检查
- 阅读JS中的单选按钮选择
- JS中的单选按钮检查不起作用
- 使用 ajax 将单选按钮的值发送到节点.js
- Knockout JS单选按钮如果所有值都为true,则选择最后一个按钮
- 统一JS单选按钮不更改状态
- 正在寻找特定的JS方法来确认单选按钮的选择
- Knockout.js中使用的唯一ID;对于“;单选按钮组中的标签属性
- 基于单选按钮状态的角度JS高亮显示行
- 单选按钮在 ajax 调用后不会更改(淘汰 js)
- 类似单选按钮的行为 Vue.js 组件
- 如何在 Angular JS 中使用 JSON 动态选择单选按钮
- 在 JS 的单选按钮元素 (HTML) 中使用 title 属性
- 如何转换我的 js 代码,以便对象的每个属性都通过输入值和单选按钮值更新
- Vue.js 使用 v-on:单击单选按钮
- 如何在角度js中将选中的单选按钮值发送到服务器
- 如果用户不接受JS确认消息,如何检查上一个选定的单选按钮
- 显示正确输出的问题.JS单选按钮的选择和添加
- Knockout.js:单选按钮第一次点击在3.0中不显示,在2.1-2.3中显示
- 需要默认选择一个角度JS单选按钮