2017-07-24 6 views
0

J'ai du mal à comprendre comment je peux lier de manière asynchrone mes champs déroulants Select2 en cascade en utilisant knockoutJS.Appliquer des liaisons de manière asynchrone dans Knockout.js

Le code fonctionne parfaitement lorsque les données à renseigner sont statiques dans la fonction, mais ne fonctionne pas lorsque vous utilisez un appel ajax asynchrone car la liaison est exécutée avant la réception de la réponse.

Quelqu'un peut-il me guider dans la bonne direction ou repérer un problème que je suis un débutant knockout.js?

Knockout

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

viewModel.togaLevels = ko.computed(function(){ 
    if(viewModel.selectedInstitution()){ 
     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 gotData = getData(); 

    return gotData.then(function() { 
     console.log('step 4 - return result'); 
     returnData = gotData; 
     return returnData; 
    }); 
} 

getData()

// Get all data from ajax call 
function getData() { 
    var data = { 'action': 'get_data' }; 
    var deferred = new jQuery.Deferred(); 

    return jQuery.post(ajaxurl, data, function(response) { 
     // console.log(response); 
     console.log('step 1 - parse ajax data'); 
     var obj = JSON.parse(response); 
     console.log('step 2 - process received data'); 
     results = processData(obj); 
    }).done(function() { 
     console.log('step 3 - ajax parsing & processing data done'); 
     console.log(results); 
     deferred.resolve(results); 
     return deferred; 
    }).fail(function() { 
     console.log('fail'); 
    }); 
} 

Répondre

1

buildData doit retourner un observable pour que votre liaison de mise à jour automatiquement une fois les modifications de données:

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

    getData().then(function(newData) { 
    console.log('step 4 - return result'); 
    dataContainer(newData); 
    }); 

    return dataContainer; // Initially empty array 
}; 

je aimerais définir personnellement le tableau dans votre viewModel d'abord bien, et écrire à l'intérieur du then en y faisant référence. Pourrait aider si vous utilisez une approche basée sur une classe/instance afin que vous puissiez référencer le dataContainer en utilisant this ... Mais je suppose que c'est une question de goût.

+0

Merci pour cela, il a été une réponse très utile et super rapide! Toi mon ami a sauvé la journée! – Ben