Load data into a Backbone collection from JSON fil

2019-01-17 21:31发布

I'm trying to load some data into a Backbone Collection from a local JSON file, using this very basic code:

  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);

In the console statement, AllStudents is empty. But init.json is definitely being loaded. It looks like this:

[
  { text: "Amy", grade: 5 },
  { text: "Angeline", grade: 26 },
  { text: "Anna", grade: 55 }    
]

What am I doing wrong?

UPDATE: I've also tried adding a reset listener above the .fetch() call, but that's not firing either:

AllStudents.bind("reset", function() {
  alert('hello world');
});
AllStudents.fetch({ url: "/init.json"});

No alert appears.

UPDATE 2: Trying this script (reproduced here in full):

$(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);
  });
});

Only one console statement even appears, in the third fetch() call, and it's an empty object.

I'm now absolutely baffled. What am I doing wrong?

The JSON file is being served as application/json, so it's nothing to do with that.

4条回答
一夜七次
2楼-- · 2019-01-17 21:50

I think you need to add {add:true} to the options of fetch,

if you assigned the fetch to a variable, you would get the result as well, but then its not inside the collection you wanted

查看更多
干净又极端
3楼-- · 2019-01-17 22:05

I/O operations in javascript are almost always asynchronous, and so it is with Backbone as well. That means that just because AllStudents.fetch has returned, it hasn't fetched the data yet. So when you hit your console.log statement, the resources has not yet been fetched. You should pass a callback to fetch:

AllStudents.fetch({ url: "/init.json", success: function() {
    console.log(AllStudents);
}});

Or optionally, use the new promise feature in jQuery (fetch will return a promise):

AllStudents.fetch({ url: "/init.json" }).complete(function() {
    console.log(AllStudents);
});
查看更多
爷、活的狠高调
4楼-- · 2019-01-17 22:05

fetch() returns a 'success' notification as already stated, but that just means that the server request was successful. fetch() brought back some JSON, but it still needs to stuff it into the collection.

The collection fires a 'reset' event when it's contents have been updated. That is when the collection is ready to use...

AllStudents.bind('reset', function () { alert('AllStudents bind event fired.'); });

It looks like you had this in your first update. The only thing I did differently was to put fetch() in front of the event binding.

查看更多
Fickle 薄情
5楼-- · 2019-01-17 22:16

The attribute names and non-numeric attribute values in your JSON file must be double quoted (" ") . Single quotes or no-quotes produces errors and response object is not created that could be used to create the models and populate the collection.

So. If you change the json file content to :

[
  { "text": "Amy", grade: 5 },
  { "text": "Angeline", grade: 26 },
  { "text": "Anna", grade: 55 }    
]

you should see the non-empty collection object.

You can change your code to see both success and failure as below:

    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');
    }
  });

For more details, probably it will be a good idea to look in to the way ajax response objects are created.

查看更多
登录 后发表回答