Backbone.js:重新填充或重新创建视图?

2023-12-09

在我的 Web 应用程序中,左侧的表中有一个用户列表,右侧有一个用户详细信息窗格。当管理员单击表中的用户时,其详细信息应显示在右侧。

我的左侧有一个 UserListView 和 UserRowView,右侧有一个 UserDetailView。事情进展顺利,但我有一个奇怪的行为。如果我单击左侧的某些用户,然后单击其中一个用户的“删除”,我会收到已显示的所有用户的连续 javascript 确认框。

看起来所有先前显示的视图的事件绑定都没有被删除,这似乎很正常。我不应该每次在 UserRowView 上都创建一个新的 UserDetailView 吗?我应该维护视图并更改其参考模型吗?我应该在创建新视图之前跟踪当前视图并将其删除吗?我有点迷失了,任何想法都会受到欢迎。谢谢 !

这是左视图的代码(行显示、单击事件、右视图创建)

window.UserRowView = Backbone.View.extend({
    tagName : "tr",
    events : {
        "click" : "click",
    },
    render : function() {
        $(this.el).html(ich.bbViewUserTr(this.model.toJSON()));
        return this;
    },
    click : function() {
        var view = new UserDetailView({model:this.model})
        view.render()
    }
})

以及右视图的代码(删除按钮)

window.UserDetailView = Backbone.View.extend({
    el : $("#bbBoxUserDetail"),
    events : {
        "click .delete" : "deleteUser"
    },
    initialize : function() {
        this.model.bind('destroy', function(){this.el.hide()}, this);
    },
    render : function() {
        this.el.html(ich.bbViewUserDetail(this.model.toJSON()));
        this.el.show();
    },
    deleteUser : function() {
        if (confirm("Really delete user " + this.model.get("login") + "?")) 
            this.model.destroy();
        return false;
    }
})

我总是销毁并创建视图,因为随着我的单页应用程序变得越来越大,将未使用的实时视图保留在内存中以便我可以重新使用它们将变得难以维护。

这是我用来清理视图以避免内存泄漏的技术的简化版本。

我首先创建一个 BaseView,我的所有视图都继承自它。基本思想是,我的视图将保留对其订阅的所有事件的引用,以便在处置视图时,所有这些绑定都将自动解除绑定。这是我的 BaseView 的示例实现:

var BaseView = function (options) {

    this.bindings = [];
    Backbone.View.apply(this, [options]);
};

_.extend(BaseView.prototype, Backbone.View.prototype, {

    bindTo: function (model, ev, callback) {

        model.bind(ev, callback, this);
        this.bindings.push({ model: model, ev: ev, callback: callback });
    },

    unbindFromAll: function () {
        _.each(this.bindings, function (binding) {
            binding.model.unbind(binding.ev, binding.callback);
        });
        this.bindings = [];
    },

    dispose: function () {
        this.unbindFromAll(); // Will unbind all events this view has bound to
        this.unbind();        // This will unbind all listeners to events from 
                              // this view. This is probably not necessary 
                              // because this view will be garbage collected.
        this.remove(); // Uses the default Backbone.View.remove() method which
                       // removes this.el from the DOM and removes DOM events.
    }

});

BaseView.extend = Backbone.View.extend;

每当视图需要绑定到模型或集合上的事件时,我都会使用 bindTo 方法。例如:

var SampleView = BaseView.extend({

    initialize: function(){
        this.bindTo(this.model, 'change', this.render);
        this.bindTo(this.collection, 'reset', this.doSomething);
    }
});

每当我删除视图时,我只需调用 dispose 方法即可自动清理所有内容:

var sampleView = new SampleView({model: some_model, collection: some_collection});
sampleView.dispose();

我与正在编写“Backbone.js on Rails”电子书的人们分享了这项技术,我相信这是他们在本书中采用的技术。

更新:2014-03-24

从 Backone 0.9.9 开始,使用上面所示的相同的 bindTo 和 unbindFromAll 技术将listenTo 和 stopListening 添加到事件中。另外,View.remove会自动调用stopListening,因此绑定和取消绑定就像现在这样简单:

var SampleView = BaseView.extend({

    initialize: function(){
        this.listenTo(this.model, 'change', this.render);
    }
});

var sampleView = new SampleView({model: some_model});
sampleView.remove();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Backbone.js:重新填充或重新创建视图? 的相关文章

  • jQuery 会在过滤选择器中的其他参数之前搜索 ID 吗?

    这个问题与性能有关 如果我使用如下选择器 myID a Does this find myID and filter by a 或者我应该这样写声明 myID find a 我不确定 jQuery 是否足够聪明 可以首先使用 ID 执行此语
  • 在 AngularJS 和 Nodejs 之间共享代码

    使用在前端和后端之间共享代码的最佳方式是什么javascript 特别是说之间nodejs and angularjs 问题是我们使用的是相同的enums and constant values例如error codes在后端和前端 现在
  • 提供文件数据时触发“drop”事件

    Question 我如何在提供文件时触发drop场的事件 其中我在加载时无权访问 Details 有一个页面 其中有一个字段 上面附加了drop掉落时处理图像的侦听器 我希望能够通过以下方式使用这个过程pasting一个图像 我知道如何从粘
  • HTML5 Canvas - 在画布上绘图、保存上下文并稍后恢复

    要求 现在 在画布上绘制 然后点击 保存 存储画布状态 离线绘制 但不作为图像 稍后 打开画布并显示之前保存的绘图 然后继续再次绘制 对于绘图 我们通常使用如下代码 canvas document getElementById can ct
  • 如果用户禁用了 javascript,如何回退到完全不同的索引页面?

    我有一个大型 动态生成的单页网站 该网站严重依赖 javascript 我想为没有 javascript 的人提供后备 每个版本必须有不同的 php 代码 所以基本上我需要一个完全不同的索引页面 我不想将所有内容都包装在 javascrip
  • Browserify 与 jQuery >= 2 生成“jQuery 需要一个带有文档的窗口”

    我正在使用 browserify 使用 CommonJS 样式的依赖项来捆绑我的前端 javascript 例如 我有 require jquery dist jquery v2 1 0 beta2 require underscore
  • 系统js语法错误,IE11

    我有一个 Angular 2 应用程序可以在 Firefox 和 Chrome 中工作 但在 IE 中却没有那么多工作 根据我的堆栈跟踪 我的 System js 设置似乎存在问题 这是我在网络控制台中看到的错误描述 Error Syste
  • 为什么 Bootstrap 按钮下拉菜单在 iOS 上不起作用?

    看起来甚至连引导演示在这里 http twitter github com bootstrap components html buttonDropdowns不适用于 iOS 您似乎无法在 iPhone 或 iPad 上从中选择项目 有解决
  • EXT JS中有全局变量吗

    在 java 和 C 中 我们可以全局存储变量并从项目中的任何位置访问它的值 比如说 我在一个名为Residence我正在保存residenceNumber这是一个INT到一个名为的全局变量houseNumberGlobalVariable
  • 闭包和异步 Node.js 函数

    All 尝试了解 Node js 上下文中的闭包 异步调用 我有以下代码 timer setInterval pollOID 1000 function pollOID for channel in channels session get
  • Django 管理中的自定义依赖下拉菜单

    我有一个按阶段模型的项目外键 我很难在 Django 管理页面中创建依赖的下拉列表 我想当用户从该项目的 项目下拉 阶段选择一个项目时 在第二个下拉菜单中显示 实现这一目标的最佳方法是什么 如果下拉列表根据其父级的值来过滤项目 那就太好了
  • 纯 JavaScript 工具提示

    我正在尝试用纯 JavaScript 制作一个工具提示 显示在hover 就像 Stack Overflow 中将鼠标悬停在个人资料名称 a 上一样div显示 我尝试使用onmouseover onmouseout并添加了setTimeou
  • 使用预先存在的数据库创建 PhoneGap iOS 应用程序

    我最近开始开发一个使用 PhoneGap 版本 2 8 0 作为药物查找器的应用程序 过去 我创建了该工具的 Web 版本 它使用 jQuery Mobile 和 PHP 来访问远程 SQL 数据库 PhoneGap 似乎是一个很有吸引力的
  • jQuery 分钟和秒倒计时器

    我想创建一个 jquery 倒计时器 我尝试了以下代码 但它不起作用 我该怎么办 DEMO https jsfiddle net tbosn210 https jsfiddle net tbosn210 var interval setIn
  • 编译器错误? g++ 允许可变大小的静态数组,除非函数是模板化的

    下面的代码演示了我无法解释的 gcc 4 6 2 的行为 第一个函数声明一个 vec t 类型的静态数组 其中 vec t 是 unsigned char 的 typedef 别名 第二个函数是相同的 只是 vect t 的类型是模板参数
  • CORS:为什么我的浏览器不发送 OPTIONS 预检请求?

    从我读到的内容来看CORS https en wikipedia org wiki Cross origin resource sharing 我理解它应该按如下方式工作 客户端的脚本尝试获取资源从服务器不同的起源 浏览器拦截这个请求并首先
  • 未捕获的类型错误:无法分配给只读属性

    我正在尝试 Nicholas Zakas 所著的 Professional JavaScript for Web Developers 一书中的这个非常简单的示例 但我不知道我在这里做错了什么 我错过了一些非常简单的事情 但我被困住了 这是
  • 什么是标志变量?

    最近我遇到了标志变量 但我不知道它们的作用 我不太确定何时使用标志变量以及如何使用它 我用 Google 搜索了它 但没有任何与我的上下文 JavaScript 相关的具体示例 标记变量的定义和使用 http www javascriptk
  • 离子选择:预选值在单击一次之前是不可见的

    我刚刚在 ionic 版本 6 中创建了一个 ion select 我的问题是 我在页面加载时已成功预选了一个值 但此预选值未显示在 UI 中 它只是在我单击选择之后出现 但在它没有出现之前 如图 2 所示 我在 ionViewWillEn
  • JQuery 循环遍历动态元素并获取数据值

    我正在尝试使用可折叠面板来完成我的要求 sport on click function var thisId this attr id var thisChildren this sportlist thisChildren each fu

随机推荐