我正在绘制一个图表,其图标大小不一(见图)。
我的主干视图“A”中的图标比例是根据我的图表模型中的一些属性计算的:availableWidth,availableHeight,yGranularity,xMax等。
当计算出图标比例时,我希望此值可用于视图A和视图B(其中B用作图表图例)。
2个问题:
1)在Backbone中,我将放置“iconSizeCalculation”,以便计算出的值可供两个视图使用。
2)在Backbone中处理不同“行为”的好方法是什么?假设视图B应仅在前面提到的(计算属性)iconSize发生变化时响应,而A应该响应大小,时间,粒度等的变化。我的具体意思是“动作”是我如何区分单属性变化与多变量 - 属性变化并做出相应的响应? (我应该计算model.changedAttributes中的属性吗?)
(或者这个问题可能源于没有以适当的方式分离View / Controller-concern?)
谢谢:)
答案 0 :(得分:3)
1) In Backbone, where would be I place the "iconSizeCalculation" so that the calculated value is available to both views.
Backbone有一个内置的事件系统,这将使这非常容易。我将假设您的显示器中有多个项目,并且图例将显示所有正在显示的项目的大小。这是一个公平的假设吗?
要设置它,我将有三个单独的视图类,都与事件相关联:
ChartView应该会收到一组Icon模型。收到此信息后,它应循环遍历图标列表,并为集合中的每个图标实例化/渲染/显示IconView。它还应该将整个集合传递给LegendView。
LegendView应循环遍历图标列表并为每个图标呈现一些文本,每个图标都使用LegendIconView。 LegendIconView应该监听来自Icon模型的change:size
事件,以便它可以知道模型的“大小”何时发生变化。更改事件将告诉您哪个图标已更新,因此您可以相应地更新图例的显示。
2) What is a good way of handling different "actions" in Backbone?
当您绑定到Backbone模型和集合中的change
事件时,您可以绑定到通用change
或特定属性更改。例如,如果您有size
属性,则可以使用以下内容收听大小更改:change:size
。这适用于模型和集合。当您在模型中收听change:size
时,它会告诉您该属性已针对该模型进行了更改。当您收听集合中的change:size
时,它会告诉您模型的大小已更改。事件args还会在集合处理程序中告诉您哪个模型已更改。
以下是您的代码可能满足您需求的粗略概念
Icon = Backbone.Model.extend({});
Icons = Backbone.Collection.extend({
model: Icon
});
ChartView = Backbone.View.extend({
initialize: function(){
_.bindAll(this, "renderIcon");
},
render: function(){
var legendView = new LegendView({collection: this.collection});
legendView.render();
$(this.el).append(legendView.el);
this.collection.each(this.renderIcon);
},
renderIcon: function(icon){
var iconView = new IconView({model: icon});
iconView.render();
$(this.el).append(iconView.el);
}
});
IconView = Backbone.View.extend({
events: {
// set up your events, to handle clicking, dragging, resizing, etc
},
render: function(){
var html = // render some html here. jquery templates, mustache, or whatever
$(this.el).html(html);
}
});
LegendView = Backbone.View.extend({
initialize: function(){
_.bindAll(this, "renderIconLegend");
},
renderIconLegend: function(icon){
var legendIconView = new LegendIconView({model: icon});
legendIconView.render();
$(this.el).append(legendIconView.el);
},
render: function(){
this.collection.each(this.renderIconLegend);
}
});
IconLegendView = Backbone.View.extend({
initialize: function(){
this.model.bind("change:size", this.updateSize, this);
},
updateSize: function(model, newSize){
var sizeEl = this.$(".sizeElement");
sizeEl.text(newSize);
},
render: function(){
var html = // render some html here
$(this.el).html(html);
}
});
var data = [{ /*some icon data*/ }, {/*more icon data*/}];
var icons = new Icons(data);
var chart = new ChartView({collection: icons});
chart.render();
$("#myChartElement").html(chart.el);
这可以让您了解所有这些是如何工作的。
当单个模型更新了size
属性时,该模型的IconLegendView实例将接收更改事件,允许您更新该图标的图例显示。