How to fetch a Backbone.js model by something other than the ID?

前端 未结 5 1325
-上瘾入骨i
-上瘾入骨i 2021-02-15 14:48

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 differe

相关标签:
5条回答
  • 2021-02-15 15:17

    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

    0 讨论(0)
  • 2021-02-15 15:19

    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");
        }
    });
    
    0 讨论(0)
  • 2021-02-15 15:29

    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();
    
    0 讨论(0)
  • 2021-02-15 15:32

    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');
        }
    });
    
    0 讨论(0)
  • 2021-02-15 15:37

    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);
          }
        });
    
    
    }
    
    0 讨论(0)
提交回复
热议问题