title: Backbone: Subview depends on another subview being rendered
body: <p>I have a Backbone SAP which has two subviews within its main App view. These are interdependent: the top one dispalys a music score rendered using <a href="http://www.vexflow.com/" rel="nofollow noreferrer">Vexflow</a> (Javascript music notation package), and the other below it displays an analysis of the score, also using Vexflow but with some extra objects (text, lines, clickable elements, etc).</p>
  
  <p>The main problem I have is that a lot of the data I need for the analysis view doesn't come into existence until the score view has been rendered. For example, the x coordinate of a musical note is only available <em>after</em> the note has been drawn (the same isn't true of the y coordinate). Below is (in schematic terms) how my app view is set up:</p>
  
  <pre><code>var AppView = Backbone.View.extend({
  
    //...
  
    initialize: function() {
      this.scoreView = new ScoreView();
      this.analysisView = new AnalysisView({
        data: this.getAnalysisData()
      });
    },
  
    render: function() {
      this.scoreView.render();
      this.analysisView.render();
      return this;
    },
  
    getAnalysisData: function() {
      // Performs anaysis of this.scoreView,
      // and returns result.
    }
  
  });
  </code></pre>
  
  <p>My work around is to move the analysis view setup into the render method, after the score view has been rendered. I dislike doing this, as the <code>getAnalysisData</code> method can be quite expensive, and I believe the render method should be reserved simply for rendering things, not processing.</p>
  
  <p>So I'm wondering if - since there doesn't seem to be a Vexflow solution - there is a Backbone pattern that might fix this. I am familiar with the 'pub/sub' event aggregator pattern for decoupling views, as in:</p>
  
  <pre><code>this.vent = _.extend({}, Backbone.Events);
  </code></pre>
  
  <p>So on this pattern the analysis view render method subscribes to an event fired after the score view is rendered. I'm not sure how this would alter my code, however. Or perhaps use <code>listenTo</code>, like this:</p>
  
  <pre><code>// Score subview.
  var ScoreView = Backbone.View.extend({
  
    initialize: function() {
      this.data = "Some data";
    },
  
    render: function() {
      alert('score');
      this.trigger('render');
    }
  
  });
  
  // Analysis subview.
  var AnalysisView = Backbone.View.extend({
  
    initialize: function(options) {
      this.data = options.data;
    },
  
    render: function() {
      alert(this.data);
      return this;
    }
  
  });
  
  // Main view.
  var AppView = Backbone.View.extend({
  
    el: "#some-div",
  
    initialize: function() {
      this.scoreView = new ScoreView();
      var view = this;
      this.listenTo(this.scoreView, 'render', this.doAnalysis); // &lt;- listen to 'render' event.
    },
  
    render: function() {
      this.scoreView.render();
      return this;
    },
  
    doAnalysis: function() {
      this.analysisView = new AnalysisView({
        data: this.getAnalysisData()
      });
      this.analysisView.render();
    },
  
    getAnalysisData: function() {
      return this.scoreView.data;
    }
  
  });
  </code></pre>
  
  <p>Of course, the analysis step is still effectively being done 'during' the render process, but this seems a better pattern. It seems more like the Backbone way of doing things. Am I right? Or am I missing something?</p>
  
  <p><strong>Edit</strong>: I dont <em>necessarily</em> have to create the analysis view in the <code>doAnalysis</code>, I could still do that in the main view <code>initialize</code> (at the moment I'm not). But <code>doAnalysis</code> <em>has</em> to run after the score view has rendered, otherwise it cannot access the relevant score geometry information.</p>