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>

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

4

1 回答 1

1

根据 antishok 的评论,为您的视图模型尝试此操作:

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;
}

​</p>

但是,我会建议一种不同的方法。我建议将所有这些数据放在服务器上,这样您就可以对 /api/studieswithsamples 进行一次调用并获取大量 JSON。然后你的代码可以被简化,但真正的好处是它只需要对服务器进行一次 HTTP 调用就可以取回你的所有代码。这可能有助于改善页面加载时间。

PS不要忘记从视图模型中返回自我。

于 2012-12-08T02:52:55.227 回答