2017-07-25 4 views
0

Ich versuche, eine kaskadierende select2-Dropdown-Liste mit knockoutJS zu füllen. Der Code scheint ordnungsgemäß zu funktionieren, wenn statische Daten wie in function staticbuildData() verwendet werden, aber bei Verwendung der Funktion function buildData() wird ein Fehler ausgegeben.Erstes Array-Objekt in ObservableArray

Uncaught TypeError: Cannot read property 'childOptions' of null

Es stellt sich heraus, dass die folgende Zeile finden nicht in der Lage ist:

Der erste Drop-down füllt die ordnungsgemäß jedoch Daten, bei Auswahl eines Elements in der ersten Dropdown-wird der folgende Fehler ausgelöst ein Kind Option und Rückkehr null:

var make = ko.utils.arrayFirst(viewModel.togaMakers,function(item) 

Das einzige, was ich denken kann, ist, dass staticbuildData() ein Array zurückkehrt, während buildData() ist ein observableArray Rückkehr und daher nicht die richtige Kind Option zu finden.

Bin ich auf dem richtigen Weg oder hat jemand eine Idee, warum das passiert?

Knockout

var viewModel = { 
    togaMakers: buildData(), 
    // togaMakers: staticbuildData(), 
    selectedInstitution : ko.observable(), 
    selectedLevel : ko.observable(), 
    selectedFaculty : ko.observable() 
}; 

viewModel.togaLevels = ko.computed(function(){ 
    if(viewModel.selectedInstitution()){ 
     console.log(buildData()); 
     var make = ko.utils.arrayFirst(viewModel.togaMakers,function(item){ 
      console.log(item.text,viewModel.selectedInstitution()); 
       return item.text===viewModel.selectedInstitution();   
     }); 
     return make.childOptions; 
    } 
}); 

viewModel.togaFaculties = ko.computed(function(){ 
    if(viewModel.selectedLevel()){ 
     var type = ko.utils.arrayFirst(viewModel.togaLevels(),function(item){ 
      console.log(item.text,viewModel.selectedLevel()); 
       return item.text===viewModel.selectedLevel(); 
      console.log("Answer:" + item); 
     }); 
     return type.childOptions; 
    } 
}); 
ko.cleanNode(viewModel); 
ko.applyBindings(viewModel); 
} 

buildData()

function buildData() { 
    var dataContainer = ko.observableArray([]); 

    getData().then(function(newData) { 
    parsed = JSON.parse(newData); 
    processed = processData(parsed); 
    dataContainer(processed); 
    }); 

    return dataContainer; 
}; 

staticBuildData

function staticbuildData(){ 
    var uomBachelor = new cascadingOption({ 
     text: 'Bachelor Degree', 
     childOptions : [ 
      new cascadingOption({ 
       text: 'Faculty of Enviroment' 
      }), 
      new cascadingOption({ 
       text: 'Faculty of Education' 
      }) 
     ] 
    }); 

    var uomMaster = new cascadingOption({ 
     text: 'Master Degree', 
     childOptions : [ 
      new cascadingOption({ 
       text: 'Faculty of Law' 
      }), 
      new cascadingOption({ 
       text: 'Faculty of Dental & Surgery' 
      }) 
     ] 
    }); 

    var uom = new cascadingOption({ 
     text: 'University 1', 
     childOptions : [uomBachelor, uomMaster] 
    }); 

    var mdx = new cascadingOption({ 
     text: 'University 2', 
     childOptions : [ 
      new cascadingOption({ 
       text:'Bachelor Degree', 
       childOptions : [ 
        {text: 'Q5'}, 
        {text: 'Q7'} 
       ] 
      }), 
      new cascadingOption({ 
       text:'Master Degree', 
       childOptions : [ 
        {text: 'A3'}, 
        {text: 'A4'}, 
        {text: 'A6'} 
       ] 
      }) 
     ] 
    }); 
    return [uom, mdx]; 
} 
+0

Kann ich Ihre HTML, oder eine jsfiddle vorzugsweise sehen. –

Antwort

1

Sie arbeiten mit asynchrone Daten Die buildData Funktion wird zuerst geben Sie ein leeres beobachtbares Array zurück, und dann fügen Sie die Daten hinzu.

Die togaLevel berechnet werden jedoch bewerten, wenn:

  • Es erste
  • selectedLevel
  • togaMakers
ändert ändert instanziiert ist

Dies bedeutet, dass Sie einen Fehler erhalten, wenn selectedLevel ist wahr, und togaMakers ist immer noch leer. Der computed Wert wird ausgewertet, es wird versucht, das erste in einem leeren Array zu finden (null zurückgeben), und dann versuchen, null.childOptions zu bekommen.

Eine schnelle Lösung wäre es, die return Aussage zu ändern:

return type ? type.childOptions : null; 

Dies macht die berechnete Griff leere Arrays von null zurück.

+0

Danke @ user3297291 für die Klärung und hilft mir, das Problem zu verstehen. Ich werde "asynchrone abhängige Observable" erforschen. – Ben

Verwandte Themen