2013-07-21 50 views
0

我使用一個很好的自定義綁定來填充JQueryUI自動完成,但我想定製它以返回Item對象,然後我可以推送不同的陣列。任何人都可以闡明如何做到這一點?謝謝!Knockout.js JqueryUI自動完成綁定 - 返回對象,而不是值

http://jsfiddle.net/rniemeyer/kEdT5/

<input data-bind="jqAuto: { autoFocus: true }, jqAutoSource: myOptions, jqAutoValue: mySelectedOption, jqAutoSourceLabel: 'name', jqAutoSourceValue: 'id'" /> 

<hr/> 

<div data-bind="text: ko.toJSON(mySelectedOption)"></div> 



    //jqAuto -- additional options to pass to autocomplete 
//jqAutoSource -- the array of choices 
//jqAutoValue -- where to write the selected value 
//jqAutoSourceLabel -- the property name that should be displayed in the possible choices 
//jqAutoSourceValue -- the property name to use for the value 
ko.bindingHandlers.jqAuto = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     var options = valueAccessor() || {}; 
     var allBindings = allBindingsAccessor(); 
     var unwrap = ko.utils.unwrapObservable; 

     //handle value changing 
     var modelValue = allBindings.jqAutoValue; 
     if (modelValue) { 
      var handleValueChange = function(event, ui) { 
       var valueToWrite = ui.item ? ui.item.value : $(element).val(); 
       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);  
       } 
      }; 

      options.change = handleValueChange; 
      options.select = handleValueChange; 
     } 

     //handle the choices being updated in a DO, so the update function doesn't have to do it each time the value is updated 
     var mappedSource = ko.dependentObservable(function() { 
      var source = unwrap(allBindings.jqAutoSource); 
      var valueProp = unwrap(allBindings.jqAutoSourceValue); 
      var labelProp = unwrap(allBindings.jqAutoSourceLabel) || valueProp; 

      var mapped = ko.utils.arrayMap(source, function(item) { 
       var result = {}; 
       result.label = labelProp ? unwrap(item[labelProp]) : unwrap(item).toString(); //show in pop-up choices 
       result.value = valueProp ? unwrap(item[valueProp]) : unwrap(item).toString(); //value 
       return result; 
      }); 
      return mapped;     
     }); 

     mappedSource.subscribe(function(newValue) { 
      $(element).autocomplete("option", "source", newValue); 
     }); 

     options.source = mappedSource(); 

     $(element).autocomplete(options); 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     //update value based on a model change 
     var allBindings = allBindingsAccessor(); 
     var modelValue = allBindings.jqAutoValue; 
     if (modelValue) { 
      $(element).val(ko.utils.unwrapObservable(modelValue));  
     } 
    } 
}; 

function Item(id, name) { 
    return { 
     id: ko.observable(id), 
     name: ko.observable(name) 
    }; 
} 

var viewModel = { 
    myOptions: ko.observableArray([ 
     new Item("One", "1 - One description"), 
     new Item("Two", "2 - Two description"), 
     new Item("Three", "3- Three description"), 
     new Item("Four", "4- Four description"), 
     new Item("Five", "5- Five description") 
    ]), 
    mySelectedOption: ko.observable() 
}; 

ko.applyBindings(viewModel); 

回答

1

您可以添加一些邏輯來了jQuery UI自動完成的選擇功能。放置在綁定處理程序中:

if (modelValue) { 
    var handleValueChange = function(event, ui) { 
     ... 
    } 

我對您的示例做了一些更改。這並不完美,但它可以成爲一個起點,我希望。 http://jsfiddle.net/dima_k/kEdT5/37/

+0

這是偉大的,感謝曾經如此很多,我試圖推動它的一個可觀察的陣列,我略微改變它,但沒有太多運氣。感謝您的幫助,我只是得到了自定義綁定的竅門!我會繼續嘗試! – Wellso

+0

不客氣。綁定處理程序非常強大,可重用。順便說一句,如果你喜歡我的答案,你可以評價它。 –

1

您可以添加一個小超時,修復它:

... 
select: function (event, ui) { 
      var selectedItem = ui.item; 

      window.setTimeout(function() { 
       $(element).val(selectedItem.koObservableValue); 
      }, 10); 
     } 

在情況下,它是一個簡單的值

... 
select: function (event, ui) { 
      var selectedItem = ui.item; 

      window.setTimeout(function() { 
       $(element).val(selectedItem); 
      }, 10); 
     } 
相關問題