【问题标题】:Backbone.js App Firing Requests Sporadically--i.e. No Request or Multiple Requests When Only One Should be FiredBackbone.js 应用程序偶尔触发请求——即仅应触发一个时没有请求或多个请求
【发布时间】:2012-12-27 18:59:51
【问题描述】:

我对 Backbone.js 比较陌生,但我认为直到现在我已经掌握了它的窍门。我有一个基本的联系人管理应用程序,但每当我单击提交按钮以创建新联系人时,它有时根本不会发送 POST 请求,但有时 Backbone.js 会发送两个或更多 POST 请求当我只打算发送一个。当我尝试通过发送DELETE 请求来删除联系人时,也会发生类似的情况。这是我的堆栈:

前端:
jQuery
下划线
骨干网
需要

后端:
节点
快递
Mongodb 和 Mongoose

我认为这是一个主干/前端问题,因为在阅读使用 Chrome 开发人员工具网络菜单发送的请求时,我看到那里有多个请求。以下是我认为是我的应用程序中的相关代码。如果你想看到更多,只是请求。我对这个问题感到很困惑,只能希望外面有人没有。谢谢!

editContact.js:(查看)

define([
  'jquery',
  'underscore',
  'backbone',
  'text!templates/editcontact.html',
  'models/contact'
], function($, _, Backbone, editContactTemplate, Contact){

  $.fn.serializeObject = function () {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function () {
      if (o[this.name] !== undefined) {
        if (!o[this.name].push) {
          o[this.name] = [o[this.name]];
        }
        o[this.name].push(this.value || '');
      } else {
        o[this.name] = this.value || '';
      }
    });
    return o;
  };

  var EditContactView = Backbone.View.extend({
    el: '.contactview',
    render: function (options) {
      var that = this;
      if (options.id) {
        that.contact = new Contact({id: options.id});
        that.contact.fetch({
          success: function (contact) {
            var template = _.template(editContactTemplate, {contact: contact});
            that.$el.html(template);
          }
        });
      } else {
        var template = _.template(editContactTemplate, {contact: null});
        this.$el.html(template);
      }
    },
    events: {
      'submit .edit-contact-form': 'saveContact',
      'click .delete': 'deleteContact'
    },
    saveContact: function (ev) {
      var contactDetails = $(ev.currentTarget).serializeObject();
      var contact = new Contact();
      contact.save(contactDetails, {
        success: function (contact) {
          Backbone.history.navigate('contacts/' + contact.id, {trigger: true});
        }
      });
      return false;
    },
    deleteContact: function (ev) {
      this.contact.destroy({
        success: function () {
          $('.contactview').html('');
          Backbone.history.navigate('', {trigger: true});
        }
      });
      return false;
      }
  });

  return EditContactView;

});

editContactTemplate.html:(模板)

<form class="edit-contact-form">
  <legend><%= contact ? 'Edit' : 'Create' %> Contact</legend>
  <label>First Name</label>
  <input type="text" name="firstname" value="<%= contact ? contact.get('firstname') : '' %>">
  <label>Last Name</label>
  <input type="text" name="lastname" value="<%= contact ? contact.get('lastname') : '' %>">
  <label>Email</label>
  <input type="text" name="email" value="<%= contact ? contact.get('email') : '' %>">
  <label>Phone Number</label>
  <input type="text" name="phonenumber" value="<%= contact ? contact.get('phonenumber') : '' %>">
  <hr>
  <button type="submit" class="btn"><%= contact ? 'Save' : 'Create' %></button>
  <% if (contact) { %>
    <input type="hidden" name="id" value="<%= contact.id %>">
    <button type="button" class="btn btn-danger delete">Delete</button>
  <% }; %>
</form>

Contact.js:(模型)

define([
  'jquery',
  'underscore',
  'backbone'
], function($, _, Backbone){

  var ContactModel = Backbone.Model.extend({
    urlRoot: '/contacts'
  });

  return ContactModel;
});

Router.js(路由器)

define([
  'jquery',
  'underscore',
  'backbone',
  'views/allcontacts',
  'views/editcontact',
  'views/contact'
], function($, _, Backbone, AllContactsView, EditContactView, ContactView){
  var AppRouter = Backbone.Router.extend({
    routes: {
    '': 'contacts',
    'newcontact': 'editContact',
    'edit/:id': 'editContact',
    'contacts/:id': 'viewContact'
    }
  });

  var initialize = function () {
    var router = new AppRouter();

    router.on('route:contacts', function() {
      var allContactsView = new AllContactsView();
      allContactsView.render();
    });
    router.on('route:editContact', function(id) {
      var allContactsView = new AllContactsView();
      allContactsView.render();
      var editContactView = new EditContactView();
      editContactView.render({id: id});
    });
    router.on('route:viewContact', function(id) {
      var allContactsView = new AllContactsView();
      allContactsView.render();
      var contactView = new ContactView();
      contactView.render({id: id});
    });

    Backbone.history.start();
  };

  return {
    initialize: initialize
  };
});

【问题讨论】:

    标签: javascript rest backbone.js requirejs underscore.js


    【解决方案1】:

    您在哪里实例化 EditContactView?您是否有可能使用相同的“el”实例化多个视图(因为这可以解释倍数)?至于缺少的请求,您是否有时会在没有模型的情况下实例化 EditContactView?

    如果没有更多信息,很难准确猜测可能出了什么问题,但这里有一个简单的调试思路:在模型上定义一个“fetch”方法,向其中添加 debugger; 行,然后调用 Backbone fetch (@987654322 @)。这样您就可以使用 Firebug/Chrome 开发工具/等。每次获取模型时暂停并检查内容。

    【讨论】:

    • 这里:在尝试您的调试建议时,我也会发布路由器代码。你能更详细地解释一下你的意思吗?我知道在 fetch 方法中将debugger; 行添加到模型中,但是我应该将Backbone.Model.fetch.apply(this, arguments); 放在哪里,它到底有什么作用?
    • 你可以把它放在调试器行之后,它的作用本质上是其他语言的super();换句话说,它调用父级(在本例中为模型)的 fetch 方法,但将“this”(模型的子类)作为“this”。通过结合这两行,您可以保留通常从 Backbone.Model 继承的所有 fetch 功能,但您仍然可以插入调试器行。
    • (附带说明一下,这实际上是一个非常有用的模式,可以通过 Backbone 学习,因为它允许您的子类在覆盖它们时调用其父类的方法。例如,您的 A 类可能从B类,B类有一个初始化函数。你希望A有自己的初始化,但你也想保持B的初始化;只需在A的初始化中执行:B.initialize.apply(this, arguments);,就可以了。)
    • 好吧:这是我使用的代码:var ContactModel = Backbone.Model.extend({ urlRoot: '/contacts' fetch: function () { debugger; Backbone.Model.fetch.apply(this); } }); 但它给了我一个Uncaught SyntaxError: unexpected identifier 错误...对不起,如果我在这方面完全是菜鸟。
    • 天哪,真的很抱歉,我把图案弄乱了,忘记了.prototype。它应该是。 Backbone.Model.prototype.fetch.apply(this) ... 很抱歉造成混乱(我希望 JS 让它变得更简单)。
    猜你喜欢
    • 1970-01-01
    • 2020-03-03
    • 2020-07-06
    • 2016-03-10
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    相关资源
    最近更新 更多