Загрузите несколько удаленных источников данных для привязки данных knockout.js

Я работаю над мастером knockout.js и мне нужно получить данные из нескольких удаленных источников данных (через AJAX), прежде чем я смогу правильно отобразить раскрывающиеся меню в мастере.

Кроме того, есть 4 раскрывающихся списка, и хотя #1 и #2 могут быть загружены первыми, #3 и #4 зависят от вариантов, выбранных в первых двух.

До сих пор я экспериментировал с использованием обещаний jQuery, а также просто вложением вызовов данных и связанных с ними обратных вызовов, но есть ли лучшие способы структурировать мой код модели представления для мастера?

Ниже приведен код загрузки данных. Я рад предоставить больше, если это необходимо.

var postobj = {
    id: workoutId
};
var getWorkout = $.post("./RowingWorkouts/GetWorkoutUsingId", postobj);
var getDiet = $.post("./Diet/GetDietUsingId", postobj);
var getFeedback = $.post("./RowingWorkouts/GetWorkoutFeedback", postobj);
// When all three are successful - I haven't gotten the when syntax to actually work yet
$.when(getWorkout, getDiet, getFeedback).done(function (workout, diet, feedback) {
    //each of the parameter is an array
    renderCharts(workout[0], diet[0], feedback[0])
    // Here are more dropdowns that depend on the choices from the above ones
    self.suggestedWorkouts = ko.observableArray();
    // pseudo-code for data call for getting suggested workouts
    $.post("./RowingWorkouts/GetSuggested", { id: selectedOldWorkout }, function(result) { 
        self.suggestedWorkouts(result);
    });

});

Это идет на несколько уровней глубже, и я бы предпочел избегать этого, если это вообще возможно. Есть ли какие-то шаблоны дизайна, которые я пропускаю, или это просто неправильно написано?

1 ответ

Решение

Вы можете использовать ленивую загрузку observable, чтобы получить данные в ваши viewModel observables и вычислить их для подписки на загрузку родительских уровней observables.

function ViewModel() {
   this.workout = ko.onDemandObservable(ViewModel.prototype.getWorkout, this);
   this.diet = ko.onDemandObservable(ViewModel.prototype.getDiet, this);
   this.feedback= ko.onDemandObservable(ViewModel.prototype.getFeedback, this);
   this.suggestedWorkouts = ko.observable();

   ko.computed(ViewModel.prototype.listsLoaded, this);
}

ViewModel.prototype.listsLoaded= function () {    
   if (this.workout.loaded() && this.diet.loaded() && this.feedback.loaded()) {
        this.loadSuggestedWorkouts();
   }
}

ViewModel.prototype.getWorkout = function () {
   ...
}

ViewModel.prototype.getDiet = function () {
   ...
}

ViewModel.prototype.getFeedback = function () {
   ...
}

ViewModel.prototype.loadSuggestedWorkouts = function () {
  ...
}
Другие вопросы по тегам