2012-07-06 10 views
6

Ich benutze knockout js und das gewählte Plugin (https://github.com/harvesthq/chosen) zu versuchen und eine gut aussehende Multi-Select zu machen.Knockout JS und ausgewählte Multiselect funktioniert nicht

Ich habe verschiedene Möglichkeiten ausprobiert, aber kann die Multiselect nicht mit den Daten arbeiten, die ich verwende. Wenn ich auf die Mehrfachauswahl klicke, werden keine Werte angezeigt, obwohl die Optionsbindung die korrekten Daten enthält.

HTML:

<select multiple="multiple" data-bind="options: allCustomers, 
selectedOptions: event().customers, optionsText: 'name', 
optionsValue: 'id', chosen: true " ></select>​ 

vereinfachte Version der View-Modell:

function Event() 
    { 
     this.customers = ko.observableArray(); 
    };      

    //for chosen plugin 
    ko.bindingHandlers.chosen = { 
     update: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
      $(element).chosen(); 
     } 
    } 

    function ViewModel() 
    { 
     this.event = ko.observable(new Event()); 
     this.allCustomers = ko.observableArray(); 
    }; 

    var viewModel = new ViewModel(); 

    $.getJSON("/get_json", function(data) 
    {         
     for (var c = 0; c < data.customers.length; c++) 
     { 
      viewModel.allCustomers.push(data.customers[c]); 
     } 
    }); 

    ko.applyBindings(viewModel); 

PHP:

function get_json() 
{ 
    $eventData = array(
     'customers' => array(array('name' => 'Bob', 'id' => 1), array('name' => 'John', 'id' => 2)), 
     'moreData' => array(), 
     'evenMoreData' => array() 
     ); 

    echo json_encode($eventData); 
} 

Dies zeigt den gewählten Stil Auswahlfeld, aber wenn ich in es klicken, Keine Optionen erscheinen.

Wenn ich ein lokales JS-Array im View-Modell für die Kunden erstellen und an allCustomers übergeben, funktioniert die Multiselect korrekt (siehe meine jsfiddle), so dass es etwas mit dem Abrufen von Daten vom Server zu tun hat, aber ich war starrt das eine Weile an und kann das Problem nicht sehen!

viel Jede Hilfe

+0

Wenn Sie 'console.log()' das Array, passt es die lokale Testversion? Sie haben keine JavaScript-Fehler auf der Seite? – Tyrsius

+0

Korrekt, keine Fehler und das Array stimmt mit der lokalen Testversion überein. – peacemaker

+1

Es könnte sein, dass der Async-Aufruf beginnt, dann werden die Bindungen angewendet, dann kehrt der Async zurück und wird zum View-Modell weitergeleitet. Wenn ich neue Kunden in das Array schiebe, werden sie nicht in der Auswahl angezeigt, was mir sagt, dass das gewählte Update nach der ersten Bindung nicht funktioniert. – Tyrsius

Antwort

16

geschätzt fand ich das Problem auch nach @Tyrsius es nicht die Daten nach der anfänglichen Bindung könnte vorgeschlagen aktualisieren.

Ich habe $(element).trigger("liszt:updated"); die Gewohnheit wie so verbindlich:

ko.bindingHandlers.chosen = { 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     $(element).chosen(); 
     $(element).trigger("liszt:updated"); 
    } 
} 
+1

Nette Arbeit, froh, dass ich helfen konnte =) – Tyrsius

+0

Danke für die Hilfe :) – peacemaker

+3

Ich wollte nur sagen, vielen Dank für diese Antwort! – Konstantin

1

Der Code in der angenommenen Version aus irgendeinem Grunde nicht für mich arbeiten. Wahrscheinlich, weil der Befehl liszt:updated nicht ausgelöst wird, um aktualisiert zu werden. Basierend auf docs here ich meine eigene Version schrieb:

ko.bindingHandlers.chosen = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     $(element).chosen({ width: "95%", placeholder_text_multiple: "Select..." }); 
     var value = ko.unwrap(valueAccessor()); 
    }, 

    update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var value = ko.unwrap(valueAccessor()); 
     $(element).trigger("chosen:updated"); 

    } 
} 
+0

Yep, Chosen geändert, um stattdessen 'gewählt: aktualisiert' zu verwenden. Siehe https://stackoverflow.com/a/18852516/484072 – peacemaker

Verwandte Themen