javascript - Backbone - 在当前 View 上绑定(bind)和取消绑定(bind)事件

标签 javascript jquery backbone.js

我试图了解是否有必要取消绑定(bind)在 view 的当前实例上绑定(bind)的事件。 .
例如,当我这样做时:

$(this.el).on('click', callback);

是否有必要取消绑定(bind)事件(例如在回调函数中使用 off()$(this).unbind('click'))或者 View 会破坏事件并将其交给垃圾收集器?

最佳答案

您应该通过 View 的事件哈希设置所有事件,并且仅在通过 .remove() 删除 View 时解除绑定(bind)。 .

主干 View 使用 Event Delegation对于 DOM 事件处理程序,因此您可以为尚不存在的 View HTML 设置事件,并且一旦生成 HTML,事件处理程序将按预期捕获事件。所有事件处理程序都附加到 View 根元素并监视该元素或其子元素中发生的特定事件。

当您通过 Backbone.View.remove() 删除 View 时,事件将解除绑定(bind)

view.remove();

如果您需要在显示 View 时取消绑定(bind)事件(不常见),您可以通过 jQuery's .off() 专门取消绑定(bind)该事件。 ,但是,您不应该(或不想)管理绑定(bind)/取消绑定(bind)您的事件。

手动解除绑定(bind)事件的问题在于,您可能/可能会很快发现自己根据用户输入有条件地解除绑定(bind)和绑定(bind)这些事件处理程序。你会走上“在这里解除绑定(bind)一个事件,在这里重新绑定(bind)它,但是当这个条件为真或这个条件为假时解除绑定(bind)”的路径……它很快就会变得困惑、脆弱和不可维护。

相反,您应该始终保持 DOM 绑定(bind),并使其执行依赖于 View 的状态……有时事件处理程序可能什么都不做,但这很好。使用这种编写 View 的方式,您只关心 DOM 事件是否正确删除了 View 。在 View 的状态中,您可以在 View 应该响应某些事件时整合其背后的业务逻辑。

在代码中,State 是什么样的?
initialize: function {
    this.state = new Backbone.Model({ /* initial state */ });
}

繁荣。就这么容易。状态只是一个对象(或主干模型),您可以在其中存储有关 View 当前状态的数据。这就像有用数据的 Views 小垃圾抽屉。

是否应该禁用保存按钮?
this.state.set('save_button_disabled', true);
this.state.set('save_button_disabled', false);

表格是否经过验证?错误?
this.state.set('form_valid', false);
this.state.set('form_errors', errorsArray);

然后将一些处理程序绑定(bind)到它,当用户做某事时,更新状态并让处理程序处理它。记录和响应状态变化将迫使您使用许多易于测试、易于命名和易于维护的小功能编写 View 。拥有一个专门的对象来存储状态是组织和整合 View 中的逻辑和条件的好方法。
this.listenTo(this.state, {
    'change:save_button_disabled': this.toggleSaveButton,
    'change:form_valid': this.onFormValidationChange
});

您还可以在 View 事件处理程序中利用状态:
events: {
    'click button.save': 'onSaveClicked'
},
onSaveClicked: function() {
    if ( this.state.get('form_valid') ) {
        /* do save logic */
    }
}

随着应用程序的增长,您可能还需要考虑将状态分为 View 状态、环境状态(测试、生产、开发、版本等)、用户状态(登录/注销、管理员、权限、用户生日等)和其他.查看状态通常是第一步。

你的 View 本质上应该是一组响应 DOM、State 和 Model/Collection 事件的简洁的小函数。应该是不是 包含评估、响应和解释用户输入和模型数据的复杂逻辑。复杂的东西应该存在于集合、模型和状态中。 View 只是这些项目和用户与之交互的界面的表示,就像 Web 应用程序的前端是用户与数据库交互的界面一样。

查看代码:
var MyView = Backbone.View.extend({
    events: {
        "click": "onClick"
    },
    "onClick": function() {
        if ( this.state.get('clickable') ) {
             /* do callback */
        }
    },
    initialize: function(options) {
        this.options = options;
        this.state = new Backbone.Model({ clickable: true });
    },
    getTemplate: function() { /*...*/ },
    render: function() {
        var template = this.getTemplate(),
            data = {
                options: this.options,
                data: this.model.toJSON(),
                state: this.state.toJSON()
            };

        return this.$el.html(template(data));
    }
});

模板代码:
{{#if state.logged_in}}
    <p {{#if options.large}}class="font-big"{{/if}}>
        Welcome back, {{data.userName}}.
    </p>
{{else}}
    <p>Hello! {{#sign_up_link}}</p>
{{/if}}

这是一个简单的例子:http://jsfiddle.net/CoryDanielson/o505ny1j/

更多关于状态和这种发展观点的方式

在一个完美的世界中, View 只是数据和应用程序的许多不同状态的交互表示。 Views are state machines. View 也是用户和数据之间的一个小缓冲区。它应该将用户的意图传递给模型/集合,并将模型/集合响应返回给用户。

更多关于这个:
  • 模型- View -意图:http://futurice.com/blog/reactive-mvc-and-the-virtual-dom
  • 模型- View -意图幻灯片:http://staltz.com/mvi-freaklies/#/
  • 另请阅读 react.js 文档以了解有关 State 的更多信息,因为它适用于 reactjs 组件,它们是比 Backbone.Views 更低级别的事物表示。 http://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html
  • 关于javascript - Backbone - 在当前 View 上绑定(bind)和取消绑定(bind)事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27236203/

    相关文章:

    ruby-on-rails - 使用 Backbone.js + Rails 更新模型不起作用(未找到 PUT 路径)

    javascript - 如何将类 ="container"的新高度设置为数据结尾?

    javascript - 如何在 html iframe 中使用 YouTube Api?

    javascript - Apple.com 产品动画

    javascript - 从 BxSlider 中移除幻灯片

    javascript - Backbone js MVC 语义建议

    javascript - 将 div 拖放到 div 上

    javascript - 自动调整网格列的宽度以显示所有数据

    javascript - 动态激活自定义类按钮

    javascript - Collection.create 中出现错误 : Uncaught Error: A "url" property or function must be specified