此(共享)逻辑是属于Backbone Model还是View或单独的实用程序?

时间:2011-10-13 11:00:47

标签: javascript model-view-controller backbone.js

我正在绘制一个图表,其图标大小不一(见图)。

我的主干视图“A”中的图标比例是根据我的图表模型中的一些属性计算的:availableWidth,availableHeight,yGranularity,xMax等。

当计算出图标比例时,我希望此值可用于视图A和视图B(其中B用作图表图例)。

2个问题:
1)在Backbone中,我将放置“iconSizeCalculation”,以便计算出的值可供两个视图使用。

2)在Backbone中处理不同“行为”的好方法是什么?假设视图B应仅在前面提到的(计算属性)iconSize发生变化时响应,而A应该响应大小,时间,粒度等的变化。我的具体意思是“动作”是我如何区分单属性变化与多变量 - 属性变化并做出相应的响应? (我应该计算model.changedAttributes中的属性吗?)
(或者这个问题可能源于没有以适当的方式分离View / Controller-concern?)

谢谢:)

enter image description here

1 个答案:

答案 0 :(得分:3)

1) In Backbone, where would be I place the "iconSizeCalculation" so that the calculated value is available to both views.

Backbone有一个内置的事件系统,这将使这非常容易。我将假设您的显示器中有多个项目,并且图例将显示所有正在显示的项目的大小。这是一个公平的假设吗?

要设置它,我将有三个单独的视图类,都与事件相关联:

  • ChartView - 代表整个图表
  • IconView - 代表要在图表上显示的各个图标
  • LegendView - 代表图表上的图例

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实例将接收更改事件,允许您更新该图标的图例显示。