Backbone 中添加了多个模态框

Multiple modals being added in Backbone

我正在从 DetailsView 打开模式

如下:

    var $ = jQuery = require('jquery'),
  Backbone = require('backbone'),
  Handlebars = require('handlebars'),
  _ = require('underscore'),
  skuDetailsTemplate = require("../../templates/sku/SkuDetails.html"),
  skuDetailsModel = require('../../models/sku/SkuDetailsModel'),
  updateSkuModel = require('../../models/sku/UpdateSkuModel'),
  skuUpdateView = require('../../views/sku/UpdateSkuView'),
  inventoryForFacilityModel = require('../../models/inventory/InventoryForFacilityModel'),
  skuListingModel = require('../../models/sku/listing/SkuListingModel');
var SkuDetailsView = Backbone.View.extend({
  el: ".sku-details-container",
  tagName: "div",
  initialize: function (options) {
    var self = this;
    this.skuDetailsModel = new skuDetailsModel();
    this.inventoryForFacilityModel = new inventoryForFacilityModel();
    this.skuListingModel = new skuListingModel();
    this.listenTo(self.skuDetailsModel, 'add', self.render);
    this.listenTo(self.skuDetailsModel, 'change', self.render);
    this.listenTo(self.inventoryForFacilityModel, 'add', self.render);
    this.listenTo(self.inventoryForFacilityModel, 'change', self.render);

    this.listenTo(self.skuListingModel, 'add', self.render);
    this.listenTo(self.skuListingModel, 'change', self.render);


    this.sku_id = options.sku_id;
    this.skuDetailsModel.set("id", this.sku_id);
    this.skuDetailsModel.fetch({});
    this.inventoryForFacilityModel.set("id", this.sku_id);
    this.inventoryForFacilityModel.fetch({})
    this.skuListingModel.set("id", this.sku_id);
    this.skuListingModel.fetch({})
  },
  events: {
    "click .openModal": "openUpdateModal",
    "click .btnEditSku": "openUpdateModal"
  },
  openUpdateModal: function (ev) {
    var data = { model: this.skuDetailsModel };
    var modalView = new skuUpdateView(data);
    modalView.show();
  },
  render: function () {
    var self = this;
    this.$el.html(skuDetailsTemplate({
      skuDetails: self.skuDetailsModel.toJSON(),
      inventoryByFacility: self.inventoryForFacilityModel.toJSON(),
      skuListing: self.skuListingModel.toJSON()
    }));
  }

});

module.exports = SkuDetailsView;

模态视图

    var UpdateSkuView = Backbone.View.extend({
  className: "modal fade",
  attributes: {
    tabindex: "-1",
    role: "dialog",
  },

  initialize: function (options) {
    var self = this;
    this.model = options.model;
    this.updateSkuModel = new updateSkuModel();
    this.template = skuUpdateTemplate;

  },
  events: {
    "click .save": "saveHandler",
    "click .closeModal": "close",
    "change .clsEdit": "recordModelChange"
  },
  recordModelChange: function (e) {
    var field = e.target.id;
    var value = e.target.value;
    var res = this.model.toJSON();
    var obj = {};

    // if (field === "length" || field === "width" || field === "height" || field === "weight" || field === "mrp" || field === "recommended_selling_price") {
    //   value = parseFloat(value);
    // }
    obj[field] = value;
    obj["id"] = res.records[0].id;
    //var res = this.model.toJSON();

    this.updateSkuModel.set(obj, { validate: true });
  },
  saveHandler: function (e) {
    //Save logic
    var self = this;
    e.preventDefault();
    var options = {
      validate: true,
      success: function (model, response) {
        self.showSuccessMessage("SKU with id " + response.records[0].id + " updated successfully");
        setTimeout(function () {
          self.close();
        }, 1500);

      }
    };
    this.updateSkuModel.save({}, options);
  },
  render: function () {
    var self = this;
    this.$el.html(this.template({
      skuDetails: self.model.toJSON()
    })).modal()

    return this;
  },

  show: function () {
    $(document.body).append(this.render().el);
  },

  close: function () {
    this.$el.remove(".modal fade");
    this.$el.modal("hide");
    this.$el.empty();
    this.undelegateEvents();

  }
});

module.exports = UpdateSkuView;

如果我打开一个模式,然后关闭它,然后打开另一个模式实例,它会覆盖前一个。

请帮忙。

我的问题:

必须更改您的关闭方法:

close: function () {
    this.undelegateEvents();
    this.$el.remove();
    this.remove();
}

因为你总是在创建一个新的模式,旧的是不必要的(垃圾)

您在此处创建模态实例:

var modalView = new skuUpdateView(data);

在这里你打开它。

modalView.show();

模态视图无法被垃圾回收,因为它是从另一个视图引用的。

您必须从您引用它的视图中关闭模式

modalView.close();

Vini,您的模态视图从不从父视图或自身调用 remove http://backbonejs.org/#View-remove

模态很难跟踪。正是出于这个原因,我使用了 Rendering bootstrap modal using backbone

尽管如此! 看看你的事件。您重新呈现父视图而不清理绑定或删除后续视图。

this.listenTo(self.skuDetailsModel, 'add', self.render);
this.listenTo(self.skuDetailsModel, 'change', self.render);
this.listenTo(self.inventoryForFacilityModel, 'add', self.render);
this.listenTo(self.inventoryForFacilityModel, 'change', self.render);

this.listenTo(self.skuListingModel, 'add', self.render);
this.listenTo(self.skuListingModel, 'change', self.render);

我感觉到 this.listenTo(self.skuListingModel, 'change', self.render); 会在您每次重新渲染/更新 "sku" 时绑定 'click event' 删除它并查看它是否有效。

解决了我的问题:

这是因为我有多个细节视图实例,所以模态被渲染了这么多次。

我是如何解决这个问题的:

给我的 DetailsView

一个独特的 $el

我使用扩展 Backbone.View 的 modalManager class 来显示模态视图。我认为你的问题出在 close 函数上,你需要隐藏模态,然后像我的 hide 函数一样将其删除。

modalManager = Backbone.View.extend({
    className: "modal",
    template: 'modals/modal.html',
    title: '',
    content: '',
    showButton: true,
    events: {
        'click .close': 'hide',
        'click .btn': 'hide'
    },
    initialize: function (options) {
        _.extend(this, _.pick(options, "title"));
        _.extend(this, _.pick(options, "content"));
        this.render();
    },
    show: function () {
        this.$el.modal('show');
    },
    hide: function () {
        this.$el.modal('hide');
        this.remove();
    },
    render: function () {
        this.$el.html(this.template({title: this.title, content: this.content, showButton: this.showButton}));
    },
    setTitle: function(title) {
        this.title=title;
        this.render();
    },
    setContent: function(content) {
        this.content=content;
        this.render();
    },
    setShowButton: function(showbutton) {
        this.showButton=showbutton;
        this.render();
    }
})