【问题标题】:Does this (shared) logic belong in Backbone Model or View or separate utility?这个(共享)逻辑是否属于主干模型或视图或单独的实用程序?
【发布时间】:2011-10-13 11:00:46
【问题描述】:

我正在绘制一个带有不同大小图标的图表(见图)。

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

计算完图标比例后,我希望视图 A 和视图 B(其中 B 用作图表图例)都可以使用此值。

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

2) 在 Backbone 中处理不同“动作”的好方法是什么?假设视图 B 仅应在上述(计算的属性)iconSize 更改时响应,而 A 应响应大小、时间、粒度等的更改。我所说的“动作”具体指的是如何区分单属性更改和多属性更改- 属性变化并做出相应反应? (我应该计算 model.changedAttributes 中的属性吗?)
(或者这个问题可能源于没有以适当的方式分离 View/Controller 关注点?)

谢谢:)

【问题讨论】:

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


    【解决方案1】:

    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 事件,以便知道模型的“大小”何时发生变化。 change 事件会告诉您哪个 Icon 已更新,因此您可以相应地更新图例的显示。

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

    【讨论】:

    • 非常感谢您提供详细的代码。我会彻底通读一遍。在我的例子中,我只有一个 Legend 图标,它应该与在另一个视图中绘制的图标具有相同的比例。我没有为特定图标使用 Backbone 模型/视图,因为它们是使用 d3.js 绘制的。我基本上只想确保无论何时更改模型中的 4 个属性(影响 iconSize)中的任何一个,两个视图都应该可以访问计算结果以使用 SVG 渲染库进行进一步渲染......!?感谢您提供任何进一步的意见:)
    • 我认为模型上的事件仍然是你想要的。您将能够通过它们获得正在更改的值的通知
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    相关资源
    最近更新 更多