2012-12-06 73 views
1

我試圖建立一個樹狀結構與一個主要的json調用抓取研究列表。從此它在另一個json調用中使用studyId。這個查詢不會總是有數據。我如何處理未定義?但是,這可能不是我的主要問題,因爲我一直無法讓這個工作正常。我會密切關注這篇文章,所以請隨時提問,我會盡快回復。謝謝!淘汰賽延遲加載和循環

// ============================================ ========= \

function StudyInfo(data) { 
    this.StudyId = ko.observable(data.StudyId); 
    this.Name = ko.observable(data.Name); 
    this.Title = ko.observable(data.Title); 
    this.Samples = ko.observableArray([]); // this field is not mapped in lazy load. 
} 
function SampleInfo(data) { 
    this.Name = ko.observable(data.Name); 
} 

function viewModel() { 
    var self = this; 
    self.Studies = ko.observableArray([]); 

    var request = $.getJSON("/api/studies"); 
    request.done(function (data) { 
     var mappedStudies = $.map(data, function (item) { 
      // now get study 
      var study = new StudyInfo(item); 
      study.Samples(self.getSamples(study.StudyId)); 
      return study; 
     }); 
     self.Studies(mappedStudies); 
    }); 
    request.fail(function (data) { 
     // error stuff not important in example 
    }); 
    self.getSamples = function (StudyId) { 
     var request = $.getJSON("/api/samples/"+StudyId()); 
     request.done(function (data) { 
      var mappedSamples = $.map(data, function (item) { 
       var sample = new SampleInfo(item); 
       return sample; 
      }); 
      return mappedSamples; 
     }); 
     request.fail(function (data) { 
      // error stuff 
     }); 
    }; 
} 

// =============================== ====================== \

<!--- list that resembles a tree --> 
<ul data-bind="foreach: Studies()"> 
    <li><a><span data-bind="text: Name"></span></a> 
      <ul data-bind="foreach: Samples"> 
       <li><a><span data-bind="Title"></span></a> 
      </ul> 
    </li> 
<ul> 

// ================== =================================== \

+0

目前還不清楚你在這裏問什麼。你在問如何處理在getSamples調用中返回的未定義值? –

+0

這是對AJAX異步特性的經典誤解。問題出在'self.getSamples'中,你從ajax done回調函數裏面返回mappedSamples',但你錯誤地認爲它會返回這個值作爲'self.getSamples'的返回值。但對self.getSamples的調用在ajax-done回調被觸發之前已經返回很久(並且因爲沒有顯式的'return'語句,它返回undefined)。 – antishok

+0

我將不得不閱讀Ajax明天的謝謝! – Calvin

回答

1

基於antishok的評論試試這個爲你的viewmodel :

function viewModel() { 
    var self = this; 
    self.Studies = ko.observableArray([]); 

    $.getJSON("/api/studies", function(allStudiesData) { 

    $.each(allStudiesData, function (index, studyData) { 

     var study = new StudyInfo(studyData); 

     // The getJSON call returns immediately and the $.each loop will 
     // loop around to the next study in allStudiesData. Later on, 
     // each time the web server returns data to us from each of the samples 
     // calls, the function(allSamplesData) will be called 
     $.getJSON("/api/samples/"+studyData.StudyId, function(allSamplesData) { 

      var mappedSamples = $.map(allSamplesData, function (sampleData) { 
       var sample = new SampleInfo(sampleData); 
       return sample; 
      }); 
      study.Samples(mappedSamples); 

      // If you put this push call outside the $.getJSON, the push would 
      // happen before the mappedSamples were added to the study 
      self.Studies.push(study);      
     });     

    }); 

    }); 

    return self; 
} 

但是,我會建議一種不同的方法。我建議將所有這些數據放在服務器上,這樣您就可以對/ api/studieswithsamples進行一次調用,並獲得大量的JSON。然後你的代碼可以被簡化,但真正的好處是它只需要一個HTTP調用服務器來獲取所有的代碼。這可以幫助改善頁面加載時間。

P.S.不要忘記從視圖模型中返回自己。

+0

感謝一個例子現在更有意義。 CodeThug我會考慮重新調用這些調用。謝謝一堆! – Calvin