主干清理元素事件

Backbone cleaning up element events

本文关键字:元素 事件      更新时间:2023-09-26

我对 Backbone 很陌生,正在努力弄清楚如何在视图之间切换时解绑元素事件。

到目前为止,我有一个加载和呈现视图的路由器......

define([
    "underscore",
    "backbone"
], function (_, Backbone) {
    "use strict";
    var Router = Backbone.Router.extend({
        "views": {},
        "routes": {
            "bugs": "listBugs",
            "*other": "showDashboard"
        },
        "listBugs": function () {
            var oRouter = this;
            require([
                "views/bugs/list"
            ], function (View) {
                oRouter.views.bugsList = new View();
                oRouter.views.bugsList.render();
            });
        },
        "showDashboard": function () {
            var oRouter = this;
            require([
                "views/dashboard"
            ], function (View) {
                oRouter.views.dashboard = new View();
                oRouter.views.dashboard.render();
            });
        }
    });
    return Router;
});

我正在仪表板视图中玩事件...

/* views/dashboard */
define([
    "underscore",
    "backbone",
    "text!templates/dashboard.html"
], function (_, Backbone, sTemplate) {
    "use strict";
    return Backbone.View.extend({
        "el": "main",
        "template": _.template(sTemplate),
        "events": {
            "click p": "testFunc"
        },
        "render": function() {
            var sHtml;
            sHtml = this.template();
            this.$el.html(sHtml);
        },
        "testFunc": function () {
            console.log("!");
        }
    });
});

问题是,如果我在/和/bug 之间单击几次,然后单击 p 标记,则会将多行写入控制台(因为正在多次创建仪表板视图),并且如果我单击错误视图中的 p 标记,则会将一行写入控制台。

当用户导航离开仪表板时,解除该单击事件绑定的最佳(也是最简单的)方法是什么?


这是错误视图,没什么大不了的...

/* views/bugs/list */
define([
    "underscore",
    "backbone",
    "text!templates/bugs/list.html"
], function (_, Backbone, sTemplate) {
    "use strict";
    return Backbone.View.extend({
        "el": "main",
        "template": _.template(sTemplate),
        "render": function() {
            var sHtml;
            sHtml = this.template();
            this.$el.html(sHtml);
        }
    });
});

如果有人感兴趣,我的解决方案

/* Router */
define([
    "underscore",
    "backbone"
], function (_, Backbone) {
    "use strict";
    var Router = Backbone.Router.extend({
        "mainView": undefined,
        "routes": {
            "bugs": "listBugs",
            "*other": "showDashboard"
        },
        "renderView": function (oView) {
            if (typeof this.mainView !== "undefined") {
                this.mainView.close();
            }
            this.mainView = oView;
            this.mainView.render();
            $("main").html(this.mainView.el);
        },
        "listBugs": function () {
            var oRouter = this;
            require([
                "views/bugs/list"
            ], function (View) {
                var oView = new View();
                oRouter.renderView(oView);
            });
        },
        "showDashboard": function () {
            var oRouter = this;
            require([
                "views/dashboard"
            ], function (View) {
                var oView = new View();
                oRouter.renderView(oView);
            });
        }
    });
    return Router;
});

.

/* /views/dashboard */
define([
    "underscore",
    "backbone",
    "text!templates/dashboard.html"
], function (_, Backbone, sTemplate) {
    "use strict";
    return Backbone.View.extend({
        "tagName": "div",
        "template": _.template(sTemplate),
        "events": {
            "click p": "testFunc"
        },
        "render": function() {
            var sHtml;
            sHtml = this.template();
            this.$el.html(sHtml);
        },
        "testFunc": function () {
            console.log("!");
        }
    });
});

.

/* /views/bugs/list */
define([
    "underscore",
    "backbone",
    "text!templates/bugs/list.html"
], function (_, Backbone, sTemplate) {
    "use strict";
    return Backbone.View.extend({
        "tagName": "div",
        "template": _.template(sTemplate),
        "render": function() {
            var sHtml;
            sHtml = this.template();
            this.$el.html(sHtml);
        }
    });
});

是否有理由在每次运行 showDasboard 方法时创建新视图?重用您的视图,您将不会遇到多个视图处理同一事件的问题:

"showDashboard": function () {
        var oRouter = this;
        require([
            "views/dashboard"
        ], function (View) {
            if(!oRouter.views.dashboard){
              oRouter.views.dashboard = new View();
            }
            if( oRouter.views.bugsList ){
              oRouter.views.bugsList.undelegateEvents();
            }
            oRouter.views.dashboard.render();
        });
    }

当然还有:

 "listBugs": function () {
        var oRouter = this;
        require([
            "views/bugs/list"
        ], function (View) {
            if(!oRouter.views.bugsList){
              oRouter.views.dashboard = new View();
            }
            if( oRouter.views.dashboard ){
              oRouter.views.dashboard.undelegateEvents();
            }
            oRouter.views.bugsList = new View();
            oRouter.views.bugsList.render();
        });
    }

然后,当您在视图的 render 方法中重新呈现其中一个视图时,您需要再次委派它们:

 this.delegateEvents();

我建议检查这个存储库:

https://github.com/RStankov/backbone-bind-to