我正在尝试在敲除中创建一个自定义绑定,其功能类似于options
默认绑定处理程序,但使用单选按钮而不是下拉菜单。
将项目添加到数组将通知,update
但选择不同的单选按钮不会。
注意:我将自定义绑定处理程序剥离到最低限度。
绑定处理程序
// LOOK FOR MY COMMENT //<------------------------------ LOOK FOR IT
ko.bindingHandlers.radioButtons = {
update: function (element, valueAccessor, allBindings) {
var unwrappedArray = ko.utils.unwrapObservable(valueAccessor());
var previousSelectedValue = ko.utils.unwrapObservable(allBindings().value);
// Helper function
var applyToObject = function (object, predicate, defaultValue) {
var predicateType = typeof predicate;
if (predicateType == "function") // Given a function; run it against the data value
return predicate(object);
else if (predicateType == "string") // Given a string; treat it as a property name on the data value
return object[predicate];
else // Given no optionsText arg; use the data value itself
return defaultValue;
};
// Map the array to a newly created label and input.
var isFirstPass = true;
var radioButtonForArrayItem = function (arrayEntry, index, oldOptions) {
if (oldOptions.length) {
var item = oldOptions[0];
if ($(item).is(":checked"))
previousSelectedValue = item.value;
isFirstPass = false;
}
var input = element.ownerDocument.createElement("input");
input.type = "radio";
var radioButtonGroupName = allBindings.get("groupName");
input.name = radioButtonGroupName;
if (isFirstPass) {
var selectedValue = ko.utils.unwrapObservable(allBindings.get("value"));
var itemValue = ko.utils.unwrapObservable(arrayEntry.value);
if (selectedValue === itemValue) {
input.checked = true;
}
} else if ($(oldOptions[0].firstElementChild).is(":checked")) {
input.checked = true;
}
var radioButtonValue = applyToObject(arrayEntry, allBindings.get("radioButtonValue"), arrayEntry);
ko.selectExtensions.writeValue(input, ko.utils.unwrapObservable(radioButtonValue));
var label = element.ownerDocument.createElement("label");
label.appendChild(input);
var radioButtonText = applyToObject(arrayEntry, allBindings.get("radioButtonText"), arrayEntry);
label.append(" " + radioButtonText);
return [label];
};
var setSelectionCallback = function (arrayEntry, newOptions) {
var inputElement = newOptions[0].firstElementChild;
if ($(inputElement).is(":checked")) {
var newValue = inputElement.value;
if (previousSelectedValue !== newValue) {
var value = allBindings.get("value");
value(newValue); //<------------------------- Get observable value and set here. Shouldn't this notify the update?
}
}
};
ko.utils.setDomNodeChildrenFromArrayMapping(element, unwrappedArray, radioButtonForArrayItem, {}, setSelectionCallback);
},
};
如何使用它...
// Html
<div data-bind="
radioButtons: letters,
groupName: 'letters',
radioButtonText: 'text',
radioButtonValue: 'value',
value: value,
"></div>
// Javascript
var vm = {
letters: ko.observableArray([
{
text: "A",
value: 1,
},
{
text: "B",
value: 2,
},
]),
value: ko.observable(2),
};
ko.applyBindings(vm);
因此,添加一个新项目vm.letters({ text: "C", value: 2 })
将通知update
. 但是,单击不同的单选按钮不会通知update
.
我需要做什么才能单击单选按钮通知update
?