2013-03-22 3 views
0

У меня есть этот базовый код JavaScript как часть проекта мини-файлового менеджера, который я делаю для удовольствия, но, к сожалению, он не работает. Внутри функции get() я пытаюсь получить доступ к массиву Content.files, но, похоже, из-за переменной области видимости или того, что внутри функции, она не устанавливает массив правильно, и на странице ничего не появляется. Firefox Error Console ничего мне не дает. Как это исправить?Доступ к 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

+0

Переменная Content.files никогда не устанавливается, поэтому доступ к ней позже в функции build() не вызывает ничего. – sableguy00

+0

Вам нужно будет вызвать 'Content.build();' внутри обратного вызова для '$ .post', поскольку' $ .post' является асинхронным. 'build' выполняется сразу после' get' в вашем комментарии к примеру, но запрос AJAX, отправленный 'get', не возвращает результаты, пока не будет вызвана' build', потому что она асинхронна – Ian

ответ

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 и она будет называться сразу же после того, как Content.files и Content.folders заполняются из запроса AJAX.

Несколько других вещей - удалите запятую после метода build в объекте Content.Кроме того, вы должны, вероятно, использовать var, чтобы объявить объекты Page и Content.

-2

Вы будете хотеть использовать this.files вместо Content.files внутри объекта. Content - ссылка, которую вы создаете для создаваемого объекта. Возможно, вы можете закрыть свое значение, как вы это делаете, я честно не знаю, но он плохо пахнет, и это действительно то, что для неявной переменной this. За пределами вашего объекта, как только он был назначен переменной Content, правильно указать Content.files, чтобы обратиться к этой переменной-члену.

Как примечание стороны, это лучше практика, чтобы вложить свой скрипт в сразу называемой анонимной функции, чтобы не рисковать сталкиваясь с другими членами window объекта, который может произойти, если вы не используете var объявить ваши переменные или вы создаете переменные за пределами области действия функции (вы делаете то и другое). Я бы прочитал более this, чтобы лучше понять это.

+0

Не против некоторых отзывов, если людям не нравится мой ответ ... – acjay

-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 заполнения должен полагаться на эту просьбу завершающим.

Смежные вопросы