Загружать данные в коллекцию Backbone из файла JSON?
Я пытаюсь загрузить некоторые данные в коллекцию Backbone из локального файла JSON, используя этот очень простой код:
window.Student = Backbone.Model.extend({
});
window.Students = Backbone.Collection.extend({
model: Student,
});
window.AllStudents = new Students();
AllStudents.fetch({ url: "/init.json"});
console.log('AllStudents', AllStudents);
В инструкции консоли AllStudents
пусто. Но init.json
определенно загружается. Это выглядит так:
[
{ text: "Amy", grade: 5 },
{ text: "Angeline", grade: 26 },
{ text: "Anna", grade: 55 }
]
Что я делаю неправильно?
ОБНОВЛЕНИЕ. Я также попробовал добавить прослушиватель reset
над вызовом .fetch()
, но не стрелял:
AllStudents.bind("reset", function() {
alert('hello world');
});
AllStudents.fetch({ url: "/init.json"});
Не появляется предупреждение.
ОБНОВЛЕНИЕ 2. Пробуйте этот script (воспроизведенный здесь полностью):
$(function(){
window.Student = Backbone.Model.extend({
});
window.Students = Backbone.Collection.extend({
model: Student,
});
window.AllStudents = new Students();
AllStudents.url = "/init.json";
AllStudents.bind('reset', function() {
console.log('hello world');
});
AllStudents.fetch();
AllStudents.fetch({ url: "/init.json", success: function() {
console.log(AllStudents);
}});
AllStudents.fetch({ url: "/init.json" }).complete(function() {
console.log(AllStudents);
});
});
В третьем вызове fetch()
появляется только один консольный оператор, и это пустой объект.
Теперь я абсолютно озадачен. Что я делаю неправильно?
Файл JSON обрабатывается как application/json, так что это не имеет никакого отношения к этому.
Ответы
Ответ 1
Имена атрибутов и значения нецифровых атрибутов в вашем файле JSON должны быть двойными (""). Одиночные кавычки или без кавычек создают ошибки, и объект ответа не создается, что может быть использовано для создания моделей и заполнения коллекции.
Итак. Если вы измените содержимое json файла на:
[
{ "text": "Amy", grade: 5 },
{ "text": "Angeline", grade: 26 },
{ "text": "Anna", grade: 55 }
]
вы должны увидеть непустой объект коллекции.
Вы можете изменить свой код, чтобы увидеть как успех, так и неудачу, как показано ниже:
AllStudents.fetch({
url: "/init.json",
success: function() {
console.log("JSON file load was successful", AllStudents);
},
error: function(){
console.log('There was some error in loading and processing the JSON file');
}
});
Для более подробной информации, вероятно, будет хорошей идеей посмотреть, как создаются объекты ответа ajax.
Ответ 2
Операции ввода/вывода в javascript почти всегда асинхронны, и так же и с Backbone. Это означает, что только потому, что AllStudents.fetch
вернулся, он еще не получил данные. Поэтому, когда вы нажимаете на свой оператор console.log
, ресурсы еще не получены. Вы должны передать обратный вызов fetch
:
AllStudents.fetch({ url: "/init.json", success: function() {
console.log(AllStudents);
}});
Или, возможно, используйте новую функцию обещания в jQuery (fetch
вернет обещание):
AllStudents.fetch({ url: "/init.json" }).complete(function() {
console.log(AllStudents);
});
Ответ 3
fetch() возвращает уведомление об успехе, как уже указано, но это означает, что запрос сервера был успешным. fetch() возвратил некоторый JSON, но ему все равно нужно занести его в коллекцию.
Коллекция обновляет событие 'reset, когда оно было обновлено. То есть, когда коллекция готова к использованию...
AllStudents.bind('reset', function () { alert('AllStudents bind event fired.'); });
Похоже, у вас это было в первом обновлении. Единственное, что я сделал по-другому, это поставить fetch() перед привязкой события.
Ответ 4
Я думаю, вам нужно добавить {add:true}
к параметрам выборки,
если вы присвоили выборке переменной, вы также получите результат,
но затем его не внутри коллекции, которую вы хотели