2013-03-22 98 views
0

我有这个基本的JavaScript代码作为一个迷你文件管理器项目的一部分,我为了好玩,但不幸的是它不起作用。在get()函数内部,我试图访问Content.files数组,但似乎由于变量的作用域或函数内部的任何内容,它没有正确设置数组,也没有任何内容出现在页面上。 Firefox的错误控制台一点也不给我。我该如何解决?JavaScript和对象访问

顺便说一句,最近我一直专注于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> 
+0

_exactly_是什么问题? – SLaks 2013-03-22 18:02:43

+0

Content.files变量从不设置,所以稍后在build()函数中访问它什么都不会。 – sableguy00 2013-03-22 18:03:36

+0

因为'$ .post'是异步的,所以你必须在'$ .post'的回调函数内调用'Content.build();'。在您的示例注释中'get'后立即执行'build',但由'get'发送的AJAX请求在调用'build'之后才会返回结果,因为它是异步的 – Ian 2013-03-22 18:05:00

回答

1

随着您删除的评论(我猜是因为我错误地删除了我自己的评论),您在拨打get后立即致电build方法。不幸的是,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,它会立即Content.filesContent.folders从AJAX请求填充后调用。

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

-2

你会想用this.files,而不是你的Content.files对象的内部。 Content是您正在创建的对象的参考。 也许你可以像你在做的那样关闭它的价值,我真的不知道,但它闻起来很糟糕,这实际上是隐含的this变量。 外部对象,一旦它被指定给变量Content,说Content.files指向该成员变量是正确的。

作为一个侧面说明,这是更好的做法,附上你的脚本在紧挨着的被称为匿名函数,以免风险与window对象的其他成员发生冲突,如果不使用var声明它可以发生你的变量,或者你创建的函数范围外的变量(你正在做这两个)。我会阅读this以更好地理解这一点。

+0

如果人们不喜欢我的答案,不介意一些反馈意见... – acjay 2013-03-22 18:14:27

-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任何依赖填充有依靠这一请求完成。