这是我编写的jQuery
UI自动完成绑定。它的目的是镜像
options,
optionsText,
optionsValue,
value与几个新增的选择要素使用绑定模式(可以查询通过AJAX选项,你可以区分什么是显示在输入框中输入与所显示的选择框弹出起来。
您无需提供所有选项。它将为您选择默认值。
//jqAuto -- main binding (should contain additional options to pass to autocomplete)//jqAutoSource -- the array to populate with choices (needs to be an observableArray)//jqAutoQuery -- function to return choices (if you need to return via AJAX)//jqAutoValue -- where to write the selected value//jqAutoSourceLabel -- the property that should be displayed in the possible choices//jqAutoSourceInputValue -- the property that should be displayed in the input box//jqAutoSourcevalue -- the property to use for the valueko.bindingHandlers.jqAuto = { init: function(element, valueAccessor, allBindingsAccessor, viewModel) { var options = valueAccessor() || {}, allBindings = allBindingsAccessor(), unwrap = ko.utils.unwrapObservable, modelValue = allBindings.jqAutoValue, source = allBindings.jqAutoSource, query = allBindings.jqAutoQuery, valueProp = allBindings.jqAutoSourcevalue, inputValueProp = allBindings.jqAutoSourceInputValue || valueProp, labelProp = allBindings.jqAutoSourceLabel || inputValueProp; //function that is shared by both select and change event handlers function writevalueToModel(valueToWrite) { if (ko.isWriteableObservable(modelValue)) { modelValue(valueToWrite ); } else { //write to non-observable if (allBindings['_ko_property_writers'] && allBindings['_ko_property_writers']['jqAutoValue']) allBindings['_ko_property_writers']['jqAutoValue'](valueToWrite ); } } //on a selection write the proper value to the model options.select = function(event, ui) { writevalueToModel(ui.item ? ui.item.actualValue : null); }; //on a change, make sure that it is a valid value or clear out the model value options.change = function(event, ui) { var currentValue = $(element).val(); var matchingItem = ko.utils.arrayFirst(unwrap(source), function(item) { return unwrap(item[inputValueProp]) === currentValue; }); if (!matchingItem) { writevalueToModel(null); } } //hold the autocomplete current response var currentResponse = null; //handle the choices being updated in a DO, to decouple value updates from source (options) updates var mappedSource = ko.dependentObservable({ read: function() { mapped = ko.utils.arrayMap(unwrap(source), function(item) { var result = {}; result.label = labelProp ? unwrap(item[labelProp]) : unwrap(item).toString(); //show in pop-up choices result.value = inputValueProp ? unwrap(item[inputValueProp]) : unwrap(item).toString(); //show in input box result.actualValue = valueProp ? unwrap(item[valueProp]) : item; //store in model return result; }); return mapped; }, write: function(newValue) { source(newValue); //update the source observableArray, so our mapped value (above) is correct if (currentResponse) { currentResponse(mappedSource()); } } }); if (query) { options.source = function(request, response) { currentResponse = response; query.call(this, request.term, mappedSource); } } else { //whenever the items that make up the source are updated, make sure that autocomplete knows it mappedSource.subscribe(function(newValue) { $(element).autocomplete("option", "source", newValue); }); options.source = mappedSource(); } ko.utils.domNodeDisposal.addDisposeCallback(element, function () { $(element).autocomplete("destroy"); }); //initialize autocomplete $(element).autocomplete(options); }, update: function(element, valueAccessor, allBindingsAccessor, viewModel) { //update value based on a model change var allBindings = allBindingsAccessor(),unwrap = ko.utils.unwrapObservable,modelValue = unwrap(allBindings.jqAutoValue) || '', valueProp = allBindings.jqAutoSourcevalue,inputValueProp = allBindings.jqAutoSourceInputValue || valueProp; //if we are writing a different property to the input than we are writing to the model, then locate the object if (valueProp && inputValueProp !== valueProp) {var source = unwrap(allBindings.jqAutoSource) || [];var modelValue = ko.utils.arrayFirst(source, function(item) { return unwrap(item[valueProp]) === modelValue;}) || {}; } //update the element with the value that should be shown in the input $(element).val(modelValue && inputValueProp !== valueProp ? unwrap(modelValue[inputValueProp]) : modelValue.toString()); }};您将使用它像:
<input data-bind="jqAuto: { autoFocus: true }, jqAutoSource: myPeople, jqAutoValue: mySelectedGuid, jqAutoSourceLabel: 'displayName', jqAutoSourceInputValue: 'name', jqAutoSourcevalue: 'guid'" />


