制定职能等到AJAX调用完成与jQuery职能、AJAX、jQuery

2023-09-10 21:09:54 作者:灭婊达人i

我试着开发一类在JavaScript中,我可以用它来访问由一个AJAX请求很容易收集到的数据的负载。唯一的问题是我需要的类成员只能访问一次的AJAX调用完成。理想的情况是什么,我想最终是一些地方由我可以在脚本中调用这个:

Im trying to develop a class in JavaScript I can use to access a load of data that is gathered by an AJAX request easily. The only problem is I need to make the members of the class accessible only once the AJAX call is complete. Ideally what I would like to end up is something where by I can call this in a script:

courses.getCourse('xyz').complete = function () {
    // do something with the code
}

这AJAX调用后,将只火已经完成,数据结构中的类是随时可以使用。理想情况下我不希望有在类中创建的每一个功能的.complete成员

And this will only fire after the AJAX call has been complete and the data structures in the "class" are ready to be used. Ideally I dont want to have to create a .complete member for every function in the class

下面是阶级我试图让至今:

Here is the "class" I am trying to make so far:

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请求完成之前,显然它不会有任何的数据访问。

At the moment getCourse will be fired before the AJAX request is complete and obviously it will have no data to access.

任何的想法会大大AP preciated,即时通讯卡在这一个!

Any ideas will be greatly appreciated, im stuck on this one!

推荐答案

下面的变化让你做出的AJAX请求只有一次,你可以打电话给你的功能如

The following changes allow you to make the AJAX request just once and you can call your function like

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 对象,因为存储的对象是在你自己的所有共享调用函数的关闭。你通常不使用混合原型(返回从一个模块一个构造函数)模块模式,除非你真的知道你在做什么,也就是关闭共享变量工作作为静态属性您的类的

As a side note, your module pattern will not work very well if you need to instantiate two of these model_courses objects, since the storage objects are all shared in your self calling function's closure. You usually don't mix the module pattern with prototypes (returning a constructor from a module), unless you really know what you are doing, that is, the shared closure variables work as static properties of your class.

这是我会做什么,如果我是你(因为你真的想私有变量)

This is what I would do if I were you (since you really want private variables)

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