JavaScript和对象访问

时间:2013-03-22 18:01:32

标签: javascript jquery ajax json object

我将这个基本的JavaScript代码作为迷你文件管理器项目的一部分,我正在为了好玩,但遗憾的是它不起作用。在get()函数内部,我正在尝试访问Content.files数组,但似乎由于变量范围或函数内部的任何内容,它没有正确设置数组,并且页面上没有任何内容。 Firefox的错误控制台什么都没给我。我该如何解决这个问题?

顺便说一句,最近我一直专注于C#和PHP,所以请原谅我,如果它只是一个愚蠢的语法错误。谢谢!

<script type="text/javascript">

Page = {

currentdir: '/',
}

Content = {

files:[], folders:[],

get: function() {

    $.post('?p=myfiles&ajax', {
        dir: '/',
    }, function (data) {
        Content.files = data.files;
        Content.folders = data.folders;
    }, "json"); 
},

build: function () {

    for (var n = 0; n < Content.files.length; n++) {

        var id = Content.files[n].id;
        var name = Content.files[n].name;
        var size = Content.files[n].size;

        output = '<td>File</td><td>'+id+'</td><td><a href="?p=file-download&id='+id+'">'+name+'</a></td><td>'+((size / (1024*1024)).toFixed(2))+' MB</td>';

        $('#filetable').append('<tr>'+output+'</tr>');

    }
},

}

</script>

3 个答案:

答案 0 :(得分:1)

根据您删除的评论(我猜是因为我错误地删除了我自己的评论),您在致电build后立即调用get方法。不幸的是,get发出了异步的AJAX请求。这意味着,在运行更多代码之前,Javascript不会等待AJAX​​响应,因此在发送请求后立即运行build。响应将在未来的某个时刻回来(从现在起不长),但几乎肯定不会在调用build之前。这意味着不会填充项目。以下是如何提供回调的示例:

var Page = {   // <-- Add `var`
    currentdir: '/',
};

var Content = {   // <-- Add `var`
    files:[],
    folders:[],
    get: function (callback) {
        $.post('?p=myfiles&ajax', {
            dir: '/',
        }, function (data) {
            Content.files = data.files;
            Content.folders = data.folders;
            //if (typeof callback !== "undefined") { // <-- Might be better than below, in the special cases where some functions are "objects" in IE
            if (typeof callback === "function") {
                Function.prototype.apply.call(this, callback, arguments);
            }
        }, "json");
    },
    build: function () {
        for (var n = 0; n < Content.files.length; n++) {
            var id = Content.files[n].id;
            var name = Content.files[n].name;
            var size = Content.files[n].size;
            output = '<td>File</td><td>'+id+'</td><td><a href="?p=file-download&id='+id+'">'+name+'</a></td><td>'+((size / (1024*1024)).toFixed(2))+' MB</td>';
            $('#filetable').append('<tr>'+output+'</tr>');
        }
    }    // <-------------- Remove the comma
};

Content.get(Content.build);

这样,您可以将任何函数引用传递给Content.get,并在从AJAX请求填充Content.filesContent.folders后立即调用它。

其他一些事项 - 删除build对象中Content方法后的逗号。此外,您应该使用var来声明PageContent个对象。

答案 1 :(得分:-1)

Content尚未定义,因为您实际上在进程中定义它,但在对象范围内,您可以使用this来引用它。帖子回调有自己的范围,但您可以在更高的范围内重新分配this

get: function() {
    var self = this;
    $.post('?p=myfiles&ajax', {
        dir: '/',
    }, function (data) {
        self.files = data.files;
        self.folders = data.folders;

http://jsfiddle.net/ExplosionPIlls/xYByU/

同样重要的是要注意,您不知道$.post方法何时完成运行,因此对Content填充的任何依赖都必须依赖该请求完成。

答案 2 :(得分:-2)

您希望在对象中使用this.files而不是Content.filesContent是您正在创建的对象的引用。 也许你可以像你一样关闭它的价值,老实说我不知道​​,但它闻起来很糟糕,而这正是隐含的this变量的用途。对象的外部,一旦将其分配给变量Content,说Content.files引用该成员变量是正确的。

作为旁注,最好将脚本封装在一个立即调用的匿名函数中,以免冒险与window对象的其他成员发生冲突,如果不使用,可能会发生这种情况。 var声明你的变量或你创建一个函数范围之外的变量(你正在做两个)。我会阅读this以更好地理解这一点。