2013-03-22 94 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任何依賴填充有依靠這一請求完成。