【问题标题】:Backbone cleaning up element events主干清理元素事件
【发布时间】:2013-11-13 10:33:34
【问题描述】:

我对 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("!");
        }
    });

});

问题是,如果我在 / 和 /bugs 之间单击几次,然后单击 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);
        }
    });

});

【问题讨论】:

    标签: javascript events backbone.js


    【解决方案1】:

    是否有理由在每次运行 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();
    

    【讨论】:

    • 没有理由,我只是对此很陌生 :) 这解决了一个问题
    • 你能显示你的错误视图来摆脱第二个吗? ;)
    • 我已将其添加到原帖中
    【解决方案2】:

    我会建议检查这个 repo:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多