淘汰懒人加载和循环

时间:2012-12-06 19:29:27

标签: jquery json knockout.js lazy-loading

我正在尝试使用一个主要的json调用构建一个树状结构,该调用可以获取一系列研究。由此它在另一个json调用中使用studyId。此查询不会始终包含数据。我如何处理undefined?但是,这可能不是我的主要问题,因为我无法使其正常工作。我会密切关注这篇文章,所以请随意提出我应该快速回答的问题。谢谢!

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

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>

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

1 个答案:

答案 0 :(得分: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。不要忘记从viewmodel返回self。