我試圖創建一個自定義的淘汰賽是像options
默認功能結合的處理程序,但使用單選按鈕,而不是一個下拉的結合。Knockoutjs單選按鈕組自定義綁定不更新的選擇
添加到數組中的項將通知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
?
我添加了一個技巧,但現在我覺得髒...'$(輸入)。在(「點擊」,函數(){var value = allBindings.get(「value」); value(this.value);});' – christo8989
我也注意到我沒有得到'vm.value'的雙向綁定。 – christo8989