6

Ich arbeite an einem Projekt, wo ich mit. NET Web API, knockout und in diesem Beispiel das jquery Plugin select2.knockout und Select2 get ausgewählt Objekt

Was versucht wird, ist einige Feldwerte nach der Änderung der Auswahl zu setzen. Die Select2-Kontrollliste wird nach einem AJAX-Aufruf geladen und die Objekte enthalten mehr Daten als nur ID und Text. Wie kann ich den Rest der Daten bekommen, damit ich die anderen Eingaben damit füllen kann? Kurz, ich versuche, ein Viewmodel nach der Änderung der Auswahl zu aktualisieren (aber ich bekomme die Daten, wenn dieses Plugin den Ajax aufruft).

Hier ist ein Beispieldaten, die das ausgewählte Objekt enthalten sollte:

{ 
    "Customer":{ 
     "ID":13, 
     "No":"0000012", 
     "Name":"SomeName", 
     "Address":"SomeAddress", 
     "ZipCode":"324231", 
     "City":"SimCity", 
     "Region":"SS", 
     "Phone":"458447478", 
     "CustomerLocations":[] 
    } 
} 

Hier ist, wo ich jetzt bin:

Beispiel html:

<input type="hidden" data-bind="select2: { optionsText: 'Name', optionsValue: 'ID', sourceUrl: apiUrls.customer, model: $root.customer() }, value: CustomerID" id="CustomerName" name="CustomerName" /> 
<input type="text" data-bind="........" /> 
<input type="text" data-bind="........" /> 
etc... 

und das ist der Brauch Bindung:

ko.bindingHandlers.select2 = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var obj = valueAccessor(), 
      allBindings = allBindingsAccessor(); 

     var optionsText = ko.utils.unwrapObservable(obj.optionsText); 
     var optionsValue = ko.utils.unwrapObservable(obj.optionsValue); 
     var sourceUrl = ko.utils.unwrapObservable(obj.sourceUrl); 
     var selectedID = ko.utils.unwrapObservable(allBindings.value); 
     var model = ko.utils.unwrapObservable(obj.model);//the object that i need to get/set 

     $(element).select2({ 
      placeholder: "Choose...", 
      minimumInputLength: 3, 
      initSelection: function (element, callback) { 
       if (model && selectedID !== "") { 
        callback({ id: model[optionsValue](), text: model[optionsText]() }); 
       } 
      }, 
      ajax: { 
       quietMillis: 500, 
       url: sourceUrl, 
       dataType: 'json', 
       data: function (search, page) { 
        return { 
         page: page, 
         search: search 
        }; 
       }, 
       results: function (data) { 
        var result = []; 
        $.each(data.list, function(key, value) { 
         result.push({ id: value[optionsValue], text: value[optionsText] }); 
        }); 
        var more = data.paging.currentPage < data.paging.pageCount; 
        return { results: result, more: more }; 
       } 
      } 
     }); 

     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $(element).select2('destroy'); 
     }); 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var obj = valueAccessor(), 
      allBindings = allBindingsAccessor(); 

     var model = ko.utils.unwrapObservable(obj.model);//the object that i need to get/set 
     var selectedID = ko.utils.unwrapObservable(allBindings.value); 

     $(element).select2('val', selectedID); 

     $(element).on("change", function (e) { 
      //... 
     }); 
    } 
}; 

Das Abrufen der ausgewählten ID oder des Textes ist kein Problem, aber wie kann man den Rest der Informationen nach dem Ajax-Aufruf nicht verlieren? Wo kann ich dieses Objekt setzen/holen, damit ich alle Daten haben kann, die es enthält?

Danke

Antwort

7

Wenn Sie eine Objektliteral für Ihre Ergebnisse bauen, das gesamte Objekt als „Daten“ Eigenschaft hinzugefügt.

result.push({ id: value[optionsValue], text: value[optionsText], data: value }); 

Dann behandeln Sie das select2-selected-Ereignis, das von select2 ausgelöst wird. Das Ereignisobjekt sollte das Objektliteral als Auswahleigenschaft enthalten.

$element.on('select2-selected', function(eventData) { 
    if (eventData.choice) { 
     // item selected 
     var dataObj = eventData.choice.data; 
     var selectedId = eventData.choice.id; 
    } else { 
     // item cleared 

    } 
}); 
+0

Ich habe diesen Vorschlag ausprobiert, aber ich sehe keine Eigenschaft mit dem Namen 'data' in der Eigenschaft' choice'. –

+1

Die Schiene war am falschen Ort. Bearbeitete die Antwort, um sicherzustellen, dass die Dateneigenschaft korrekt eingestellt ist. –

+0

Alan, deine Bearbeitung wurde abgelehnt, aber sie war korrekt. Ich habe den Code behoben ... danke. –

1

Für select2 v4 können Sie $(elem).select2('data') verwenden, um die ausgewählten Objekte zu erhalten.

$('selected2-enabled-elements').on('change', function(e) { 
    console.log($(this).select2('data')); 
}); 

Beispiel: https://jsfiddle.net/calvin/p1nzrxuy/

0

Für select2 Versionen vor v4.0.0 können Sie tun:

.on("select2-selecting", function (e) { 
    console.log(e.object); 
}) 

Von v4.0.0 auf und aufwärts sollten folgende Arbeiten:

.on("select2-selecting", function (e) { 
    $(this).select2('data') 
}) 
Verwandte Themen