Backbone.js:如何只处理单个视图的选择
Backbone.js: How to handle selection of a single view only?
我遇到了以下问题:
我有一个模型,它有一个属性来定义它是否被明显地选中,为了这个问题的目的,我将称之为SelectModel。
SelectModel = Backbone.Model.extend({
defaults:{
isSelected: false
}
})
现在,我真正不明白的第一部分是我应该如何处理一般的选择。如果我想使用observer模式,我的View应该监听isSelected属性的更改。但我的观点也从一开始就引发了这种情况,所以我会这样做的。
SelectView = Backbone.View.extend({
initialize: function(){
this.model.bind("change:isSelected", this.toggleSelectionVisually)
},
events: {
"click" : toggleSelection
},
toggleSelection: function(){
this.model.set({"isSelected": !this.model.get("isSelected");
},
toggleSelectionVisually:(){
//some code that shows that the view is now selected
},
})
所以这本身就已经感觉有点荒谬了,但我想我只是理解了一些错误。
但是,在不让代码变得糟糕的情况下,我真正无法实现的部分是处理多个模型的选择,即一次只选择一个模型。
SelectListView = Backbone.View.extend({
initialize: function(){
this.collection = new SelectList();
},
toggleSelection: function(){
????
}
})
那么,谁应该通知谁选择的变更呢?哪个部分应该触发它,哪个部分应该倾听?我真的被这个卡住了。对于一个视图来说,这是可行的,对于一个集合来说,我很难过地失去了。
在看到问题的第二部分之前,我会建议对您的SelectView
进行以下简化:
SelectView = Backbone.View.extend({
events: {
"click" : toggleSelection
},
toggleSelection: function(){
this.model.set({"isSelected": !this.model.get("isSelected");
//some code that shows whether the view is selected or not
}
});
然而,由于isSelected
属性显然是互斥的,当打开另一个属性时,可以隐式地关闭它,我认为您拥有它的方式最适合您的情况。
因此,使用现有的SelectView
和,您可以得到如下的SelectListView
警告:每次选择一个模型时,它都会遍历整个模型集合。如果您将有大量的模型,这将不能很好地扩展,并且您希望缓存以前选择的模型,而不是在整个集合上迭代
SelectListView = Backbone.View.extend({
initialize: function(){
this.collection = new SelectList();
this.collection.bind('change:isSelected', this.toggleSelection, this);
},
toggleSelection: function(toggledModel){
//A model was toggled (on or off)
if(toggledModel.get('isSelected') {
//A model was toggled ON, so check if a different model is already selected
var otherSelectedModel = this.collection.find(function(model) {
return toggledModel !== model && model.get('isSelected');
});
if(otherSelectedModel != null) {
//Another model was selected, so toggle it to off
otherSelectedModel.set({'isSelected': false});
}
}
}
});
我建议您的模型不要跟踪这一点,而是跟踪视图。
在我看来,模型与它的显示无关,而是与你正在跟踪的数据有关。该视图应该封装关于数据在哪里以及如何显示给用户的所有信息
所以我会把isSelected
作为视图的一个属性。然后,编写一个切换可见性的方法是很琐碎的。如果您需要解释选择了特定视图的其他视图,您可以附加一个侦听器$(this.el).on('other_visible', toggle_show)
,该侦听器可以在$(this.el).trigger('other_visible')
的toggle_visibility
方法上触发
非常接近@rrr建议的解决方案,但将逻辑从View
移动到Collection
,我认为它会变成:
SelectsCollection = Backbone.Collection.extend({
initialize: function() {
this.on( "change:selected", this.changeSelected );
},
changeSelected: function( model, val, opts ){
if( val ){
this.each( function( e ){
if( e != model && e.get( "selected" ) ) e.set( "selected", false );
});
};
},
});
有不同的方法可以做到这一点。您可以在集合本身上触发一个事件,并让所有SelectModel实例侦听它并相应地更新自己。如果集合中有很多SelectModel实例,这似乎有点浪费,因为它们中的大多数最终都不会做任何工作。我可能会做的是跟踪您视图中的最后一个SelectModel:
SelectListView = Backbone.View.extend({
initialize: function(){
this.collection = new SelectList();
this.lastSelectedModel = null;
},
toggleSelection: function(){
// populate newSelectedModel with the SelectedModel that you're toggling
var newSelectedModel = getNewSelectedModel();
if (!newSelectedModel.get('isSelected')) {
// if the SelectModel isn't already selected, we're about to toggle it On
// so we need to notify the previously selected SelectModel
if (this.lastSelectedModel) {
this.lastSelectedModel.set({isSelected: false});
}
this.lastSelectedModel = newSelectedModel;
} else {
// if the newSelectedModel we're about to toggle WAS already selected that means
// nothing is selected now so clear out the lastSelectedModel
this.lastSelectedModel = null;
}
newSelectedModel.set({isSelected: !newSelectedModel.get('isSelected')});
}
})
- 在不破坏未定义函数的情况下,对多个视图使用单个js文件
- 如何在具有某些 UI 视图的状态中管理工厂单个请求数据
- 创建从单个模板继承的多个动态视图
- 用不同的数据并排呈现单个jsp/html页面(可比较的视图)
- 在单个视图上重复多个 ng
- 通过 Ajax 将多个表单数据发布到 Django 中的单个视图
- 主干.js单个集合项视图
- 如何在单个主干视图中使用多个 JST 模板
- 需要在单个页面上使用角度 js 中的单独模块的两个视图
- Knockoutjs:如何将单个项目从可观察数组传递到我的视图模型中
- 用于添加编辑视图的单个html文件或多个文件
- 角度视图(如果未经过身份验证)显示单个视图
- Backbone.js:如何只处理单个视图的选择
- 在Angular JS中为单个视图添加完整的页面背景
- 绑定带有单个记录的简单视图模型
- BackboneJS:从不同的视图修改单个模型
- 在单个视图中应用多个视图模型的不同方式
- 如何在Sencha touch 2中使用Ajax数据更新单个视图容器项html
- BackboneJS:如何在单个视图中分配多个模型
- 如何使用两个<脚本>'s在单个视图页中