如何检查用户是否确认了自定义模式对话框

How to check if a user confirmed a custom modal dialog

我正在尝试使用 backbone js 来实现模态 window,但是当我 运行 代码时,它每次都会进行搜索。我以为我可以创建一个变量并将其赋值为 1 或 0,然后在我的代码中检查它,但我似乎无法正确访问它。

这是我的两个文件: ModalView.js

var modalTemplate = "<div id=\"pivotModal\" class=\"modal\">" +
        "<div class=\"modal-header\"><h3><%- title %></h3><button class=\"dtsBtn close\">Close</button></div>" +
    "<div class=\"modal-body\"><h3>Are you sure you want to remove <strong>all</strong> results from your query?</h3></div>" +
    "<div class=\"modal-footer\"><button " +
    "class=\"dtsBtn cancel\">Cancel</button><button " +
    "class=\"dtsBtn confirm\">Confirm</button></div>" +
    "</div>" +
    "<div class=\"modal-backdrop\"></div>";

var ModalView = Backbone.View.extend({

    defaults: {
        title: 'Not Set',
        isConfirmed: '0'
    },

    initialize: function (options) {
        this.options = options;
        this.options = _.extend({}, this.defaults, this.options);
        this.template = _.template(modalTemplate);
        console.log('Hello from Modal View: ' + this.options.title);
    },

    events: {
        'click .close': 'close',
        'click .cancel': 'cancel',
        'click .modal-backdrop': 'close',
        'click .confirm': 'confirm',
    },


    render: function () {
        var data = {title: this.options.title}
        this.$el.html(this.template(data));
        return this;
    },

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

    close: function () {
        console.log('Closed');
        this.unbind();
        this.remove();
    },

    cancel: function () {
        console.log('Cancelled');
        this.unbind();
        this.remove();
    },

    confirm: function () {
        console.log('Confirmed');
        this.options.isConfirmed = 1;
        console.log(this.options.isConfirmed)
        this.unbind();
        this.remove();
    }

});

modal_test.js(上面的代码 运行):

$('.clearAll').on("click", function(e) {
    e.preventDefault();
    var _title = "Confirm Action";
    //pass the value of the item we clicked on to the title variable
    var modal = new ModalView({ title : _title });
    modal.show();
    if (modal.isConfirmed === 1) {
        console.log("Confirmed equals 1")
        clearAllSearch.startSearch();
        masterSearch.startSearch();
    }
});

一切都独立工作,但我无法将 if 语句获取到 运行。

如何实现自定义确认模式

实现模式的一种方法是将回调函数传递给视图。

ModalView.show({
    title: _title,
    callback: function(confirmed) {
        if (!confirmed) return; // early return
        console.log("User confirmed")
        clearAllSearch.startSearch();
        masterSearch.startSearch();
    }
});

像这样实现视图的地方:

var ModalView = Backbone.View.extend({
    template: _.template(modalTemplate),
    events: {
        'click .close': 'close',
        'click .cancel': 'close',
        'click .modal-backdrop': 'close',
        'click .confirm': 'confirm',
    },
    initialize: function (options) {
        this.options = _.extend({ title: 'Are you sure?' }, options);
    },
    render: function () {
        this.$el.html(this.template(this.options));
        return this;
    },
    show: function () {
        $(document.body).append(this.render().el);
        return this;
    },
    close: function () {
        this.remove();
        var cb = this.options.callback;
        if (cb) cb(false);
    },

    confirm: function () {
        this.remove();
        var cb = this.options.callback;
        if (cb) cb(true);
    }
}, {
    // Static function
    show: function(options) {
        return new ModalView(options).show();
    }
});

使用承诺

除了回调,您还可以使用 Promise but it's not available in all browsers yet. An easy alternative would be to use jQuery deferred、jQuery 的承诺实现。

    initialize: function(options) {
        this.options = _.extend({ title: 'Are you sure?' }, options);
        this.deferred = $.Deferred();
    },
    show: function () {
        $(document.body).append(this.render().el);
        return this.deferred;
    },
    close: function () {
        this.remove();
        this.deferred().reject();
    },

    confirm: function () {
        this.remove();
        this.deferred().resolve();
    }

它将标准化处理异步确认的方式。

ModalView.show({ title: _title }).then(function() {
    console.log("User confirmed")
    clearAllSearch.startSearch();
    masterSearch.startSearch();
});

您的代码有什么问题?

看起来你在调用 modal.isConfirmed 但模态视图 class 正在将 isConfirmed 放入 options 属性.

this.options = _.extend({}, this.defaults, this.options);

如果您使用 modal.options.isConfirmed,它可能 return 是正确的值,但您可以在视图上创建一个简单的访问器函数。

isConfirmed: function() {
    return this.options.isConfirmed;
}

并且由于 isConfirmed 是一个布尔标志,您应该将其设置为 true,而不是像 01.

这样的任意整数

然后你可以调用 if (modal.isConfirmed()),它会 return 正确的值。

但是,您还有另一个问题:显示模态的时刻和用户与模态交互的时刻是异步

var modal = new ModalView({ title : _title });
modal.show();
// This will always be false since the user hasn't clicked anything yet.
if (modal.isConfirmed === 1) {

这是通过首先显示的回调技术解决的。


其他可能的改进

每次实例化模态视图时,您都在创建模板函数,而您可以在定义 class.

时创建一次
var ModalView = Backbone.View.extend({
    template: _.template(modalTemplate), // define the template here
    initialize: function (options) {
        // this.options = options; // useless line
        this.options = _.extend({}, this.defaults, options);
    },