title: backbone, javascript mvc - styling views with javascript
body: <p>A few of my views need their textareas converted to rich text editors.</p>
  
  <p>I'm using jwysiwyg as the editor. It requires that the element it is being attached to is in the page when the editor is initialized i.e. when I call $(this.el).wysiwyg(), this.el is already in the document.</p>
  
  <p>Most of my views do not actually attach themselves to the dom - their render methods simply set their elements html content using the apps templating engine e.g. $(this.el).html(this.template(content) </p>
  
  <p>Views/Controllers further up the chain look after actually inserting these child views into the page. At the same time, views do re-render themselves when their models change.</p>
  
  <p>How do I ensure that the editor is attached to the element every time its rendered and still ensure that the editor is not attached until the element is already in the page?</p>
  
  <p>Obviously I could hack something together that would work in this particular case but I would like an elegant solution that will work for all cases.</p>
  
  <p>Any help would be much appreciated.</p>
  
  <p>Edit: The main point here is that the solution must scale gracefully to cover multiple elements that must be styled after rendering and must not be styled until they are in the DOM</p>
  
  <p>Edit: This is not an issue if I do top-down rendering but this is slow, I'd like a solution whereby I can render from the bottom up and then insert the complete view in one go at the top</p>
  
  <p>Edit:</p>
  
  <p>Using a combination of some of the techniques suggested below I'm thinking of doing something like the following. Any comments/critique would be appreciated.</p>
  
  <pre><code>app/views/base_view.js:
  
  initialize: function() {
    // wrap the render function to trigger 'render' events
    this.render = _.wrap(this.render, function() {
      this.trigger('render')
    });
  
    // bind this view to 'attach' events. 
    // 'attach' events must be triggered manually on any view being inserted into the dom
    this.bind('attach', function() {
      this.attached();
      // the refreshed event is only attached to the render event after the view has been attached
      this.bind('render', this.refreshed())
      // each view must keep a record of its child views and propagate the 'attach' events
      _.each(this.childViews, function(view) {
        view.trigger('attach')
      })
    })
  }
  
  // called when the view is first inserted to the dom
  attached: function() {
    this.style();
  }
  
  // called if the view renders after it has been inserted
  refreshed: function() {
    this.style();
  }
  
  style: function() {
    // default styling here, override or extend for custom
  }
  </code></pre>