Question

Let's say I have one root Ractive on the page,and various widgest to show when an hypothetic backbone router navigate to a route :

var widget1=Ractive.extend({template:"<div>{{foo}}</div>"});
var widget2=Ractive.extend({template:"<div>{{bar}}</div>"});

var view=new Ractive({
   template:"<nav></nav><widget />",
   components:{widget:widget1}
});

var Router=Backbone.Router.extend({/* the code ... */})

so widget1 would be shown when I navigate to /widget1 and widget2 when the route is /widget2,

What would be the best way to swap widgets depending on the current route without creating seperate root Ractives or hiding/showing widgets? thanks.

Was it helpful?

Solution

An alternative solution to my previous suggestion, which allows routes to be set in a more dynamic fashion (i.e. without having to declare them in a template up-front):

<nav>...</nav>

<!-- we have a single <route> component representing all possible routes -->
<route current='{{currentRoute}}'/>

This could be implemented like so:

Ractive.components.route = Ractive.extend({
  template: '<div class="container"></div>',
  init: function () {
    this.container = this.find( '.container' );

    this.observe( 'current', function ( currentRoute ) {
      var View = routes[ currentRoute ];

      if ( this.view ) {
        this.view.teardown();
      }

      this.view = new View({
        el: this.container
      });
    });
  }
});

Then, to switch routes:

router.on( 'route', function ( route ) {
  ractive.set( 'currentRoute', route );
});

With this approach all you'd need to do is register all the possible routes at some point in your app:

routes.widget1 = Ractive.extend({template:"<div>{{foo}}</div>"});

...and so on. If necessary you could interact with each view object by retrieving a reference:

route = ractive.findComponent( 'route' );
route.view.on( 'someEvent', someEventHandler );

OTHER TIPS

One way would be to explicitly include the components representing each route in the top-level template:

<nav>...</nav>

{{# route === 'widget1' }}
  <widget1/>
{{/ route === 'widget1' }}

{{# route === 'widget2' }}
  <widget2/>
{{/ route === 'widget2' }}

Then, you could do something like:

router.on( 'route', function ( route ) {
  ractive.set( 'route', route );
});

This would tear down the existing route component and create the new one.

If your route components had asynchronous transitions, you could ensure that the new route didn't replace the old route until any transitions had completed by doing this:

router.on( 'route', function ( route ) {
  ractive.set( 'route', null, function () {
    ractive.set( 'route', route );
  });
});

(Note that as of version 0.4.0, ractive.set() will return a promise that fulfils when any transitions are complete - though callbacks will still be supported.)

Having said all that I'd be interested to hear about any other patterns that people have had success with.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top