How to fetch a Backbone.js model by something othe

2019-03-27 08:27发布

问题:

Backbone.js's default, RESTful approach to fetching a model by the ID is easy and straight-forward. However, I can't seem to find any examples of fetching a model by a different attribute. How can I fetch a Backbone.js model by a different attribute?

var Widget = Backbone.Model.extend({
    urlRoot: '/widgets',
    fetchByName: function(){ ... }
});
var foowidget = new Widget({name: 'Foo'});
foowidget.fetchByName();

回答1:

You can try doing something like this on your base model definition or on demand when calling fetch.

model.fetch({ data: $.param({ someParam: 12345}) });

In your case, along the lines of.

var Widget = Backbone.Model.extend({
    initialize: function(options) {
        this.name = options.name;        
    },
    urlRoot: '/widgets',
    fetchByName: function(){ 
        this.fetch({ data: $.param({ name: this.name }) }) 
    }
});

var foowidget = new Widget({name: 'Foo'});
foowidget.fetchByName();


回答2:

One approach is to override Backbone.sync() method, either for all classes or for just your class. However, presumably your goal is to override fetch for just a single model. One way to do that is to directly call jQuery.ajax(...), and on success, take the response and set that, e.g.

fetchByName: function() {
   var self = this;

    $.ajax({
      url: self.urlRoot+ "?name="+this.get('name'),
      type: 'GET',
      contentType: "application/json; charset=utf-8",
      dataType: "json",
      success: function(data) {
          self.set(data);
      }
    });


}


回答3:

If the model is part of a collection you can use where() to pull out the models matching some criteria.

See http://backbonejs.org/#Collection-where



回答4:

I really like the approach suggested by 'user645715'. I have adjusted the code to be more versatile. If you add this to a Backbone Model it will allow you to search the server by one or more attributes, and should work as a direct drop-in replacement for fetch.

fetchByAttributes: function(attributes, callbacks) {

    var queryString = [];
    for(var a in attributes){
        queryString.push( encodeURIComponent(a)+'='+encodeURIComponent(attributes[a]) );
    }
    queryString = '?'+queryString.join('&');

    var self = this;

    $.ajax({
        url: this.urlRoot+queryString,
        type: 'GET',
        dataType: "json",
        success: function(data) {
            self.set(data);
            callbacks.success();
        },
        error: function(data){
            callbacks.error();
        }
    });
}

It can be used like this:

var page = new Page();
page.fetchByAttributes({slug:slug}, {
    success: function(){
        console.log('fetched something');
    },
    error: function(){
        console.log('nothing found');
    }
});


回答5:

this is simple model.fetch is same as $.ajax in some way

model = Backbone.Model.extend({
    urlRoot: "/root/"
});

var Model = new model();

Model.fetch({
    beforeSend: function () {
        console.log("before");
    },
    data: {
        param1: "param1",
        param2: "param2"
    },
    success: function () {
        console.log("success");
    },
    error: function () {
        console.log("failure");
    }
});


标签: backbone.js