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.