Skip to content

Instantly share code, notes, and snippets.

@erikringsmuth
Last active August 29, 2015 13:55
Show Gist options
  • Save erikringsmuth/8747543 to your computer and use it in GitHub Desktop.
Save erikringsmuth/8747543 to your computer and use it in GitHub Desktop.
Ractive.js Layouts

Ractive Layout Views

I'd like to propose a new Ractive feature. The goal is to use a JavaScript router to load a view without an intermediate step to render the layout (header, footer, etc.). In most frameworks you have to start the "App" then start the router. The "App" is the layout and the router loads and populates the main content. I prefer to have the router run the app without an intermediate step to render the layout. The router should load a view, let's start with the HomeView, and the HomeView should specify a LayoutView. Creating the home view should also create and render the layout. When you attach the home view to the document you're also attaching it's layout.

Here's an example:

// layout/layoutView.js
define([
  'ractive',
  'text!layout/layoutTemplate.html'
], function(Ractive, layoutTemplate) {
  'use strict';

  // a simple layout
  return Ractive.extend({
    template: layoutTemplate
  });
});
// home/homeView.js
define([
  'ractive',
  'text!home/homeTemplate.html',
  'layout/layoutView'
], function(Ractive, homeTemplate, LayoutView) {
  'use strict';

  // the home view extends the layout
  return LayoutView.extend({
    components: {
      contentplaceholder: Ractive.extend({ // and set's itself in the contentplaceholder component
        template: homeTemplate
      })
    }
  });
});

This works but isn't ideal. The home view has to know what component it's attaching to. It would be cleaner if the home view could simply specify a layout property and have the layout specify what component to attach to. The layout could specify a contentPlaceholder for the child to attach to. This way it would look like this.

// layout/layoutView.js
define([
  'ractive',
  'text!layout/layoutTemplate.html'
], function(Ractive, layoutTemplate) {
  'use strict';

  // a simple layout
  return Ractive.extend({
    template: layoutTemplate,
    contentPlaceholder: contentplaceholder // This time the layout specifies where the child goes (an alias to a component)
  });
});
// home/homeView.js
define([
  'ractive',
  'text!home/homeTemplate.html',
  'layout/layoutView'
], function(Ractive, homeTemplate, LayoutView) {
  'use strict';

  // the 'HomeView' has a layout property this time instead of extending the layout
  return Ractive.extend({
    template: homeTemplate,
    layout: LayoutView
  });
});

This is a good start but it would be even better if the HomeView had an outerEl property in addition to it's el property. The outerEl would refer to the layout's el. You could attach it to the document using homeView.outerEl.

Now you can use a router to load homeView.js, render it, and attach it to the document. When the route changes you do the same thing for the next view. The RequireJS Router is the example I've been working on. This completely decouples the layout from the router.

I think this could be implemented using Ractive components. The layout and contentPlaceholder properties would simply tell the Ractive view's how to attach the child view to the layout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment