我试图用JavaScript开发一个类,我可以用它来访问由AJAX请求轻松收集的数据量。唯一的问题是我需要在AJAX调用完成后才能访问类的成员。理想情况下,我希望最终得到的是我可以在脚本中调用它的内容:
courses.getCourse('xyz').complete = function () {
// do something with the code
}
这只会在AJAX调用完成并且“类”中的数据结构准备好使用之后才会触发。理想情况下,我不想为类中的每个函数创建.complete成员
这是我到目前为止所做的“课程”:
var model_courses = (function() {
var cls = function () {
var _storage = {}; // Used for storing course related info
_storage.courses = {}; // Used for accessing courses directly
_storage.references = new Array(); // Stores all available course IDs
var _ready = 0;
$.ajax({
type: "GET",
url: "data/courses.xml",
dataType: "xml",
success: function(xml) {
$(xml).find("course").each(function() {
_storage.courses[$(this).attr('id')] = {
title : $(this).find('title').text(),
description : $(this).find('description').text(),
points : $(this).find('points').text()
}
_storage.references.push($(this).attr('id'))
})
}
})
console.log(_storage.courses)
}
cls.prototype = {
getCourse: function (courseID) {
console.log(cls._storage)
},
getCourses: function () {
return _storage.courses
},
getReferences: function (),
return _storage.references
}
}
return cls
})()
目前getCourse将在AJAX请求完成之前被触发,显然它没有数据可供访问。
任何想法都将受到高度赞赏,我坚持这一点!
答案 0 :(得分:3)
jQuery已经使用延迟对象为你处理了这个问题,除非我误解了你在寻找什么。
var courses = {
getCourse: function (id) {
return $.ajax({url:"getCourse.php",data:{id:id});
}
};
courses.getCourse("history").done(function(data){
console.log(data);
});
我知道这并不是你想要的,我希望这足以让你朝着正确的方向前进。延迟对象非常棒。
答案 1 :(得分:1)
以下更改允许您只进行一次AJAX请求,并且可以像
一样调用您的函数courses.getCourse('xyz', function(course){
// Use course here
});
以下是更改
var model_courses = (function() {
// This is what gets returned by the $.ajax call
var xhr;
var _storage = {}; // Used for storing course related info
_storage.courses = {}; // Used for accessing courses directly
_storage.references = []; // Stores all available course IDs
var cls = function () {
xhr = $.ajax({
type: "GET",
url: "data/courses.xml",
dataType: "xml",
success: function(xml) {
$(xml).find("course").each(function() {
_storage.courses[$(this).attr('id')] = {
title : $(this).find('title').text(),
description : $(this).find('description').text(),
points : $(this).find('points').text()
}
_storage.references.push($(this).attr('id'))
});
}
});
}
cls.prototype = {
// Made changes here, you'd have to make the same
// changes to getCourses and getReferences
getCourse: function (courseID, callback) {
if (xhr.readyState == 4) {
callback(_storage.courses[courseID]);
}
else {
xhr.done(function(){
callback(_storage.courses[courseID]);
})
}
},
getCourses: function () {
return _storage.courses
},
getReferences: function (),
return _storage.references
}
}
return cls
})()
作为旁注,如果需要实例化其中两个model_courses
对象,则模块模式将无法正常工作,因为存储对象都在自调用函数的闭包中共享。您通常不会将模块模式与原型混合(从模块返回构造函数),除非您确实知道自己在做什么,也就是说,共享闭包变量作为类的静态属性
如果我是你(因为你真的想要私人变量),我会这样做。
function ModelCourses() {
var storage = {
courses: {},
references: []
};
var xhr = $.ajax({
type: "GET",
url: "data/courses.xml",
dataType: "xml",
success: function(xml) {
$(xml).find("course").each(function() {
storage.courses[$(this).attr('id')] = {
title : $(this).find('title').text(),
description : $(this).find('description').text(),
points : $(this).find('points').text()
}
storage.references.push($(this).attr('id'))
})
}
});
this.getCourse = function(courseId, callback) {
function getCourse() {
callback(storage.courses[courseID])
}
if (xhr.readyState == 4) {
getCourse();
}
else {
xhr.done(getCourse);
}
};
}
答案 2 :(得分:0)
getStorage
中的要么添加一个检查以查看是否有任何数据要盗窃(首选),要么将“实际”方法设为私有,而不是在它可以访问的项目时公开它。 (我会推荐第一个,否则你会得到关于调用一个对象上不存在的方法的例外。)
答案 3 :(得分:0)
您可以定义一个执行ajax请求的函数getData
,并将getCourse
作为回调。
getData
可能在本地存储Ajax调用的结果,并在执行ajax调用之前测试本地存储。
您还可以指定一个私有成员,以允许ajax调用只运行一次。 您可能需要查看underscore.js以获取一些方便的工具
这是一个简短的示例代码:
cls.prototype.getData = function(callback) {
/*perform ajax call or retrieve data from cache*/
callback()
}
cls.prototype.getCourse = function(id) {
this.getData(function() {
/*do something with the data and the id you passed*/
}
}