Backbone collection fetch (add:true) does not upda

2019-04-24 08:35发布

loadMore: function(){
    var $this = this;
    console.log(this.Messages); //SAME AS AFTER
    this.Messages.url = '/js/messages/?start=' + this.Messages.length
    this.Messages.fetch({'add':true,
        success:function(){
            console.log($this.Messages); //SAME AS BEFORE??
        },
        error:function(){
        }
    });
 },

The collection is not updated. After this function, the events are fired, and the new items are drawn on the screen. The problem is that the collection did not add the new models.

4条回答
地球回转人心会变
2楼-- · 2019-04-24 09:16

Backbone 1.0 removes this feature, breaking code that depends on this:

http://backbonejs.org/#Collection-fetch

Compare with:

"If you'd like to add the incoming models to the current collection, instead of replacing the collection's contents, pass {add: true} as an option to fetch."

http://htmlpreview.github.com/?https://raw.github.com/documentcloud/backbone/0.9.2/index.html#Collection-fetch

I suggest reverting to an older version of Backbone until this issue is fixed.

查看更多
Evening l夕情丶
3楼-- · 2019-04-24 09:18

Backbone.Collection.fetch():

fetch: function(options) {
  options = options ? _.clone(options) : {};
  if (options.parse === void 0) options.parse = true;
  var success = options.success;
  options.success = function(collection, resp, options) {
    var method = options.update ? 'update' : 'reset';
    collection[method](resp, options);
    if (success) success(collection, resp, options);
  };
  return this.sync('read', this, options);
},

So what's up here is, your passed in function is assigned to var succees.
collection[method](resp, options); Is called and in your case method is 'reset'.
collection.reset has to go through and add all your models, fire all the events on the way. I don't know exactly what's going on but it goes through collection.reset, collection.add, model.add, etc...I didn't follow it all.

I'm not sure what the problem is exactly, I'm sorry about that. I hope I can at least help you try some things so maybe we can figure it out. The line if (success) success(collection, resp, options) is the call to your succes function. What you might try doing is having your success callback accept the passed back arguments and do some consoling of those out:

success: function(collection, resp, options) {
  console.log(collection); // this might do the trick.

  // if not, you could try the following
  collection.on("reset", function(c, options) {
    console.log(c); // see what that gives ya.
  });
}

Another thing is, I couldn't find anywhere in the source or the docs where collection.fetch takes an add option. If I missed it, please let me know I'd like to look it over.

Good luck, let me know what you find. It might be worth trailing through with a step through debugger too.

Shit, it strikes me also that console has often showed me the most up to date version of collection objects when it shouldn't have.

try consoling out the lenghts of the collections instead or something:

var len = $this.Messages.length;
console.log(len);


//...
// or in the success callback
var len = collection.length;
console.log(len);
查看更多
成全新的幸福
4楼-- · 2019-04-24 09:23

As was mentioned in a previous answer the add option was removed in 1.0.0. You can accomplish the same thing by passing remove: false instead. From the docs:

The behavior of fetch can be customized by using the available set options. For example, to fetch a collection, getting an "add" event for every new model, and a "change" event for every changed existing model, without removing anything: collection.fetch({remove: false})

查看更多
The star\"
5楼-- · 2019-04-24 09:26

in backbone 1.0, you have to trigger reset by hand:

youColloection.fetch({reset: true});
查看更多
登录 后发表回答