Backbonejs事件多次发生

Ale*_*Gad 23 backbone.js

我有一个视图显示网格中的项目.如果单击用于创建新行的按钮,则会显示一个弹出窗口(使用SimpleModal)以允许用户将该行保存到服务器.如果一切顺利,窗口关闭,网格刷新.到目前为止,一切正常.如果我现在再次打开窗口,保存记录事件将被调用两次.如果我第三次关闭并打开窗口,那么事件将被调用三次,等等.我不知道为什么事件会多次反弹.这是我的两个观点:

FieldList查看:

var fieldListView = Backbone.View.extend({
el: "#centerbodycontent",
initialize: function () {
    _.bindAll(this, 'render', 'addField');
},

render: function () {
    $(this.el).empty();
    $("#FieldGridTemplate").tmpl({ results: this.model }).appendTo(this.el)
    stripe($(this.el).find("tbody"));
    return this;
},
events: {
    "click a#addfield": "addField"
},
addField: function (e) {
    window.appController.popup = new fieldFormView({ model: new fieldModel({ contenttype_id: this.model.id }) });
    window.appController.popup.render();
}
Run Code Online (Sandbox Code Playgroud)

});

表单视图(这是弹出窗口的调用)

var fieldFormView = Backbone.View.extend({
el: "#popupwindowcontent",

events: {
    "click #savefieldandnew": "savefield",
    "click #savefieldandclose": "savefield",
    "change input,textarea,select": "changeField"
},
render: function () {
    var formWrapper = $(this.el).find(".modal-form")[0];
    $(formWrapper).empty();
    $("#FieldFormTemplate").tmpl({ results: this.model }).appendTo(formWrapper)
    OpenForm(this.el, "Add Field", 450, 600);
    return this;
},
// automatically updates the model during field changes
changeField: function (e) {
    var changeobj = new Object;
    switch (e.target.type) {
        case "radio":
            changeobj[e.target.id] = parseInt($(e.target).val());
            break;
        case "checkbox":
            changeobj[e.target.id] = $(e.target).is(":checked");
            break;
        default:
            changeobj[e.target.id] = $(e.target).val();
            break;
    }

    if (e.target.id.toLowerCase() == "name") {
        var k = $(this.el).find("#key");
        if (jQuery.trim(k.val()).length == 0)
            k.val($(e.target).val().replace(/[^a-zA-Z0-9]+/g, '').toLowerCase());

        var l = $(this.el).find("#label");
        if (jQuery.trim(l.val()).length == 0)
            l.val($(e.target).val());
    }

    var options = { silent: true };
    this.model.set(changeobj, options);
},
savefield: function (e) {
    var kcode = (e.which);
    var thiz = this;
    var m = this.model;
    var nextaction = e.target.id;
    alert(nextaction);
    if (kcode == 0 || kcode == 1 || kcode == 32) {
        e.preventDefault();
        if ($("#contentfieldform").validate({
            rules: {
                name: { required: true },
                label: { required: true },
                key: { required: true }
            }
        }).form()) {
            m.save(null, {
                headers: { "If-Match": m.get("version") },
                error: function (model, response) {
                    var errResp = JSON.parse(response.responseText);
                    popupException("Content Type Modification Error", errResp.errors[0].message);
                },
                success: function (model, response) {
                    window.appController.popup.model = new fieldModel;
                    $.pnotify({
                        pnotify_title: 'Field Saved',
                        pnotify_text: 'The field was saved successfully.'
                    });

                    if (nextaction == "savefieldandclose") {
                        $.modal.close();
                    }
                }
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*Gad 23

由于没有人回答我以为我会添加一些更多的信息,万一有人遇到这个.一个很好的资源来解释所发生的事情(和提供一个通用的解决方案)是http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/.此外,最新版本的骨干网有一些新方法允许从视图中取消注册事件.


小智 5

今天早上我也有同样的头痛,但发现了一个小小的解决方法,对我来说就像一个魅力.

主要思想是每次我们需要显示某些东西时避免创建新的View对象,而是尝试重用旧的视图对象.就我而言,它看起来像这样:

   Overview: backBone.View.extend({
        el: $('#overviewTab'),

        dialog : null,
Run Code Online (Sandbox Code Playgroud)

对话框是我的字段,我将在其中保存我的视图对象

现在在创建新视图的回调上我这样做:

showNewActivityDialog: function () {
            this.dialog = this.dialog || new window.RTB.Views.NewActivity();
            this.dialog.render();
            return false;
        },
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我不创建新的视图 - 我重用以前创建的,所以我不绑定新事件!
希望它对你有用