我试图了解是否有必要取消绑定(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 也是用户和数据之间的一个小缓冲区。它应该将用户的意图传递给模型/集合,并将模型/集合响应返回给用户。
更多关于这个:
关于javascript - Backbone - 在当前 View 上绑定(bind)和取消绑定(bind)事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27236203/