Jquery 击退延迟加载和循环
我正试图构建一个树状结构,其中包含一个主json调用,该调用获取一个研究列表。由此,它在另一个json调用中使用studyId。此查询并不总是包含数据。如何处理未定义的?然而,这可能不是我的主要问题,因为我一直无法让它正常工作。我会一直关注这篇文章,所以请随意提问,我会尽快回复。谢谢 //=====================================================\Jquery 击退延迟加载和循环,jquery,json,knockout.js,lazy-loading,Jquery,Json,Knockout.js,Lazy Loading,我正试图构建一个树状结构,其中包含一个主json调用,该调用获取一个研究列表。由此,它在另一个json调用中使用studyId。此查询并不总是包含数据。如何处理未定义的?然而,这可能不是我的主要问题,因为我一直无法让它正常工作。我会一直关注这篇文章,所以请随意提问,我会尽快回复。谢谢 //=====================================================\ function StudyInfo(data) { this.StudyId = ko.o
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>
//=====================================================\
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>
-
-
//=======================================================\根据antishok的评论,为您的viewmodel尝试以下操作:
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>
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调用就可以收回所有代码。这有助于缩短页面加载时间
注意:别忘了从viewmodel返回self。根据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调用就可以收回所有代码。这有助于缩短页面加载时间
另外,别忘了从viewmodel返回self。这里不清楚你在问什么。您是否在问如何处理getSamples调用中返回的未定义值?这是对AJAX异步本质的典型误解。问题出在
self.getSamples
中,您从ajax done回调函数内部返回mappedSamples
,但您错误地认为它将返回此值作为self.getSamples
的返回值。但是对self.getSamples的调用早在ajax完成回调触发之前就已经返回了(而且因为没有显式的return
语句,它返回的是未定义的)。明天我必须阅读ajax,谢谢!不清楚你在问什么。您是否在问如何处理getSamples调用中返回的未定义值?这是对AJAX异步本质的典型误解。问题出在self.getSamples
中,您从ajax done回调函数内部返回mappedSamples
,但您错误地认为它将返回此值作为self.getSamples
的返回值。但是对self.getSamples的调用早在ajax完成回调触发之前就已经返回了(而且因为没有显式的return
语句,它返回的是未定义的)。明天我必须阅读ajax,谢谢!谢谢你的例子,现在更有意义了。我会考虑重新接电话。非常感谢!谢谢你的例子,现在更有意义了。我会考虑重新接电话。非常感谢!