我正在尝试了解是否有必要取消绑定在view
的当前实例上绑定的事件。
例如,当我这样做时:
$(this.el).on('click', callback);
是否有必要取消绑定事件(例如在回调函数中使用off()
或$(this).unbind('click')
),或者视图可能会破坏事件并将其提供给垃圾收集器?
答案 0 :(得分:5)
您应该通过View的事件哈希设置所有活动,并在通过.remove()
删除视图时解除绑定。
Backbone Views使用Event Delegation作为DOM事件处理程序,因此您可以为尚未存在的View HTML设置事件,并且一旦生成HTML,事件处理程序将捕获事件正如所料。所有事件处理程序都附加到views根元素,并监视该元素或其子元素中发生的特定事件。
删除视图时,系统将不受约束view.remove();
如果您需要在显示视图时解除绑定事件(不常见),您可以通过jQuery's .off()专门取消绑定该事件,但是,您不应该(或想要)管理绑定/解除你的事件。
手动取消绑定事件的问题在于,您可能/可能会很快发现自己有条件地解除绑定并根据用户输入绑定这些事件处理程序。你将沿着这条路走下去,在这里解开一个事件,在这里重新绑定它,但是当这个条件成立或者这个条件是假的时候解除绑定" ......它会很快变得混乱,脆弱和无法维护
相反,你应该始终保持你的DOM绑定绑定并让它们的执行依赖于视图的 State ...有时候事件处理程序可能什么都不做,但是那个'很好。使用这种写作视图样式,您只关注DOM事件就是您正确地删除了您的视图。在视图状态内,您可以在视图响应某些事件时合并后面的业务逻辑。
initialize: function {
this.state = new Backbone.Model({ /* initial state */ });
}
动臂。 这很简单。状态只是一个对象(或骨干模型),您可以在其中存储有关视图当前状态的数据。它就像是有用数据的视图小垃圾抽屉。
是否应禁用保存按钮?
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);
然后将一些处理程序绑定到它,当用户执行某些操作时,更新状态并让处理程序处理它。记录和响应状态更改将强制您使用易于测试,易于命名和易于维护的许多小功能编写视图。拥有一个专用的存储状态对象是组织和整合逻辑的好方法。视野中的条件。
this.listenTo(this.state, {
'change:save_button_disabled': this.toggleSaveButton,
'change:form_valid': this.onFormValidationChange
});
您还可以在视图事件处理程序中点击状态:
events: {
'click button.save': 'onSaveClicked'
},
onSaveClicked: function() {
if ( this.state.get('form_valid') ) {
/* do save logic */
}
}
随着应用程序的增长,您可能还希望将状态分为查看状态,环境状态(测试,产品,开发,版本等),用户状态(登录/注销,管理员,权限,用户生日等等) ) 和别的。查看状态通常是第一步。
您的视图本质上应该是一堆响应DOM,State和Model / Collection事件的小型简洁函数。它应该不包含评估,响应和解释用户输入和模型数据的复杂逻辑..复杂的东西应该存在于集合,模型和状态中。视图只是用户与其交互的那些项和界面的表示,就像web-app的前端是用户与数据库交互的界面一样。
查看代码:
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/
在完美的世界中,视图仅仅是数据的交互式表示以及应用程序的许多不同状态。 Views are state machines.视图也是用户和数据之间的一个小缓冲区。它应该将用户对模型/集合的意图以及模型/集合响应转发回用户。
更多相关信息: