Backbone意外地发出了多个ajax请求

时间:2016-03-04 04:57:53

标签: javascript ajax backbone.js

我将fetch url与deferred方法放在一起,我希望它只会调用一次远程ajax请求。

但是,当我加载页面时,它会调用三次。

我该如何解决?感谢

js脚本

var Comments = Backbone.Collection.extend({
    model: Comment,
    url: fetch_comments_url,
    initialize: function() {
        this.fetch({
            success: this.fetchSuccess,
            error: this.fetchError
        });
        this.deferred = new $.Deferred();
    },
    deferred: Function.constructor.prototype,
    fetchSuccess: function(collection, response) {
        collection.deferred.resolve();
    },
    fetchError: function(collection, response) {
        throw new Error("Products fetch did get collection from API");
    },
var comments = new Comments();

...

comments.deferred.done(function() {
    commentView.render();
    emptyCommentView.render();
});

强制执行js脚本

var Comments = Backbone.Collection.extend({
    model: Comment,
    url: fetch_comments_url,
    initialize: function() {
        this.fetch({
            success: this.fetchSuccess,
            error: this.fetchError
        });
        this.deferred = new $.Deferred();
    },
    deferred: Function.constructor.prototype,
    fetchSuccess: function(collection, response) {
        collection.deferred.resolve();
    },
    fetchError: function(collection, response) {
        throw new Error("Products fetch did get collection from API");
    },
    wellFormedComments: function () {
        var MESSAGE_LIMIT_LENGTH = 80
        var models = comments.select(function (model) {
          var msg = model.get("message")
          if (msg!=null) {
            msg = msg.replace(/^\s+|\s+$/g, '')
            if (msg.length >= MESSAGE_LIMIT_LENGTH) {
              model.set("preview_message", msg.substr(0, MESSAGE_LIMIT_LENGTH/2));
            } else{
            };
            return true
          }
          else{
              return false
          };
        });
        return new Comments(models);
    },
    emptyComments: function () {
        var models = comments.select(function (model) {
          var msg = model.get("message")
          return false===_(msg).notBlank();
        });
        return new Comments(models);
    }
    });
var comments = new Comments();
var CommentView = Backbone.View.extend({
    el: $("#comments_section"),
    render: function() {
        var notNullComments = comments.wellFormedComments();
        if (notNullComments.length > 0) {
            $("#dadasay_comments_plugin").show();
        }
        var html = commentsTmpl(notNullComments.toJSON());
        $(this.el).append(html);
    },
});
var EmptyCommentView = Backbone.View.extend({
    el: $("#empty_comments_list"),
    render: function() {
        var source = $('#empty_comments_list_tmpl').html();
        var emptyComments = comments.emptyComments();
        var html = emptyCommentsTmpl(emptyComments.toJSON());
        $(this.el).html(html);
    },
});
var commentView = new CommentView({
    collection: comments
});
var emptyCommentView = new EmptyCommentView({
    collection: comments
});
comments.deferred.done(function() {
    commentView.render();
    emptyCommentView.render();
});

1 个答案:

答案 0 :(得分:2)

问题是您的评论集合在初始化时会触发fetch。它的方法wellFormedCommentsemptyComments创建了新的注释集合,因此它们也会触发提取。

您可以通过在需要时手动触发提取来解决此问题,例如:

var Comments = Backbone.Collection.extend({
  model: Comment,
  url: fetch_comments_url,
  wellFormedComments: function() {
    var MESSAGE_LIMIT_LENGTH = 80
    var models = this.select(function(model) {
      var msg = model.get("message")
      if (msg != null) {
        msg = msg.replace(/^\s+|\s+$/g, '')
        if (msg.length >= MESSAGE_LIMIT_LENGTH) {
          model.set("preview_message", msg.substr(0, MESSAGE_LIMIT_LENGTH / 2));
        } else {};
        return true
      } else {
        return false
      };
    });
    return new Comments(models);
  },
  emptyComments: function() {
    var models = this.select(function(model) {
      var msg = model.get("message")
      return false === _(msg).notBlank();
    });
    return new Comments(models);
  }
});
var CommentView = Backbone.View.extend({
  el: $("#comments_section"),
  render: function() {
    var notNullComments = comments.wellFormedComments();
    if (notNullComments.length > 0) {
      $("#dadasay_comments_plugin").show();
    }
    var html = commentsTmpl(notNullComments.toJSON());
    $(this.el).append(html);
  },
});
var EmptyCommentView = Backbone.View.extend({
  el: $("#empty_comments_list"),
  render: function() {
    var source = $('#empty_comments_list_tmpl').html();
    var emptyComments = comments.emptyComments();
    var html = emptyCommentsTmpl(emptyComments.toJSON());
    $(this.el).html(html);
  },
});
var comments = new Comments();
var commentView = new CommentView({
  collection: comments
});
var emptyCommentView = new EmptyCommentView({
  collection: comments
});

comments.fetch({ // <--------- Do this manually once
  success: function() {
    commentView.render();
    emptyCommentView.render();
  },
  error: function() {}
});

我认为您可以更好地构建代码,如下所示,希望注释解释更改

var Comments = Backbone.Collection.extend({
  model: Comment,
  url: fetch_comments_url,
  wellFormedComments: function() {
    var MESSAGE_LIMIT_LENGTH = 80
    var models = this.select(function(model) {
      var msg = model.get("message")
      if (msg != null) {
        msg = msg.replace(/^\s+|\s+$/g, '')
        if (msg.length >= MESSAGE_LIMIT_LENGTH) {
          model.set("preview_message", msg.substr(0, MESSAGE_LIMIT_LENGTH / 2));
        }
        return true
      }
      return false

    });
    return new Comments(models);
  },
  emptyComments: function() {
    var models = this.select(function(model) {
      var msg = model.get("message")
      return false === _(msg).notBlank();
    });
    return new Comments(models);
  }
});
var CommentView = Backbone.View.extend({
  el: $("#comments_section"),
  template: commentsTmpl, // template reference, better create it here
  initialize: function() {
    this.render(); // self rendering
  },
  render: function() {
    if (this.collection.length) { // use this.collection to refer to view's collection rather than external variables
      $("#dadasay_comments_plugin").show(); //This shouldn't be a global selection
    }
    var html = this.template(this.collection.toJSON());
    this.$el.append(html);
    //---^ use cached jQuery object rather than creating new one
  },
});
var EmptyCommentView = Backbone.View.extend({
  el: $("#empty_comments_list"),
  template: emptyCommentsTmpl,
  initialize: function() {
    this.render();
  },
  render: function() {
    var source = $('#empty_comments_list_tmpl').html(); // unused?
    var html = this.template(this.collection.toJSON());
    this.$el.html(html);
  },
});
var comments = new Comments();

comments.fetch({ // <--------- Do this manually once
  success: function(collection, response) {
    //----------------^ comments collection, all comments
    var commentView = new CommentView({
      collection: collection.wellFormedComments() // pass the resuting collection
    });
    var emptyCommentView = new EmptyCommentView({
      collection: collection.emptyComments() // pass the resuting collection
    });
  },
  error: function() {}
});