meteor-blaze-components icon indicating copy to clipboard operation
meteor-blaze-components copied to clipboard

Q: Is Iron Router able to render components via yield?

Open rclai opened this issue 10 years ago • 33 comments

Router.route('/', {
  name: 'MyRoute',
  template: 'MyComponent'
});

rclai avatar May 01 '15 13:05 rclai

Hm, no. :-( This would just render the logic-less template content. Not a component. You could probably do template: MyComponent.renderComponent() there.

mitar avatar May 01 '15 20:05 mitar

It seems it should work easily. You just have to use a controller with a different lookupTemplate method. This overrides it. But you could easily create a controller class which just inherits from RouteController.

var originalLookupTemplate = RouteController.prototype.lookupTemplate;
RouteController.prototype.lookupTemplate = function () {
  if (var component = BlazeComponent.getComponent(this.lookupOption('template'))) {
    return component.renderComponent();
  }
  return originalLookupTemplate.apply(this);
};

mitar avatar May 01 '15 22:05 mitar

Now that I am thinking, probably it could be possible to create a JavaScript class which is both an RouteController and a Blaze Component. That would be an interesting combination.

mitar avatar May 01 '15 22:05 mitar

Oh wow, thanks for looking that up so fast. I think I will just use that prototype patch for now but were you thinking of doing something in particular with Iron Router or can I just close this?

rclai avatar May 03 '15 01:05 rclai

We could probably made that into a package. Or push them upstream with a weak dependency in iron-router.

mitar avatar May 03 '15 06:05 mitar

Does it work or does it not work?

mitar avatar May 06 '15 23:05 mitar

It does, sorry I messed up.

rclai avatar May 07 '15 03:05 rclai

So what did you want to do about this? Did you want to create a package for making BC compatible with IR?

rclai avatar May 07 '15 18:05 rclai

Patch into Meteor changing all necessary bits to have officially all extension points needed by Blaze Components was just merged into its development branch: https://github.com/meteor/meteor/commit/eff8016b5a7a981fc56beb531ece52de5b3d7101

Based on that I made this pull request to Iron Router: https://github.com/iron-meteor/iron-dynamic-template/pull/11

If it is merged in Blaze Components should work out of the box with iron router.

mitar avatar May 10 '15 22:05 mitar

@rclai: Could you test if using that branch of Iron Router works for you? (You do not have to upgrade to latest Meteor, because at the moment Blaze Components monkey-patch it with what was currently merged in.)

mitar avatar May 10 '15 22:05 mitar

Try with 0.9.1 version.

mitar avatar May 11 '15 05:05 mitar

Are you talking about this branch?

rclai avatar May 11 '15 21:05 rclai

Yes.

mitar avatar May 11 '15 21:05 mitar

For some reason I got this error:

Conflict: Constraint iron:[email protected] is not satisfied by iron:layout 1.0.0-pre3.
Constraints on package "iron:layout":
* iron:layout@=1.0.0-pre3 <- top level
* iron:[email protected] <- iron:router 1.0.7 <- profab:core 0.1.0
* iron:[email protected] <- iron:controller 1.0.7 <- iron:router 1.0.7

rclai avatar May 11 '15 21:05 rclai

Why you have a top level constraint on 1.0.0-pre3?

mitar avatar May 11 '15 21:05 mitar

Oh whoops I forgot to git checkout patch-template.

rclai avatar May 11 '15 21:05 rclai

Okay, my routes error out with this now:

TypeError: undefined is not a function
    at [object Object].Controller (packages/iron:controller/lib/controller.js:23:1)
    at new Controller.extend.constructor (packages/iron:router/lib/route_controller.js:14:1)
    at [object Object].ctor (packages/iron:core/lib/iron_core.js:88:1)
    at Function.Router.createController (packages/iron:router/lib/router.js:201:1)
    at Function.Router.dispatch (packages/iron:router/lib/router_server.js:39:1)
    at Object.router (packages/iron:router/lib/router.js:15:1)
    at next (/root/.meteor/packages/webapp/.1.2.0.xaqlky++os+web.browser+web.cordova/npm/node_modules/connect/lib/proto.js:190:15)
    at Object.Package [as handle] (packages/cfs:http-methods/http.methods.server.api.js:425:1)
    at next (/root/.meteor/packages/webapp/.1.2.0.xaqlky++os+web.browser+web.cordova/npm/node_modules/connect/lib/proto.js:190:15)
    at Function.app.handle (/root/.meteor/packages/webapp/.1.2.0.xaqlky++os+web.browser+web.cordova/npm/node_modules/connect/lib/proto.js:198:3)

rclai avatar May 11 '15 21:05 rclai

You will have to give more information. :-) Like, what exactly does not work.

mitar avatar May 11 '15 21:05 mitar

BTW, you do not need the patch above anymore.

mitar avatar May 11 '15 21:05 mitar

Huh? So am I supposed to just upgrade to 0.9.2 and that's it?

rclai avatar May 11 '15 21:05 rclai

Yes. Just upgrade to 0.9.2 and use the patch-template branch of dynamic-template.

mitar avatar May 11 '15 21:05 mitar

Oh, well it's not working, for some reason it (iron layout branch) breaks iron:controller and I can't visit any route. It shows the error in the client-side.

rclai avatar May 11 '15 21:05 rclai

Hm. Can you make a small example where it breaks?

mitar avatar May 11 '15 21:05 mitar

I'll try that later, but the error happens here.

rclai avatar May 11 '15 21:05 rclai

This is really strange. I think there is maybe some mismatch of versions you have? Do you have everything on your latest version? What does .meteor/versions say?

mitar avatar May 11 '15 21:05 mitar

I found a way to render a Blaze Component without having to use the lookupTemplate monkey-patch. You would have to use the action function unfortunately.

Router.route('/my-route', {
  'name': 'routeName',
  action: function () {
    // My solution to make sure the component doesn't get re-rendered in case I had 
    // multiple routes using the same template. In most cases you won't need this check.
    if (!BlazeComponent.getComponentForElement($('#MyComponentId').get(0))) {
      this.render(BlazeComponent.getComponent('MyComponentRegisteredName').renderComponent());
    }
  }
});

rclai avatar May 12 '15 14:05 rclai

The easiest solution I found is to simply wrap the component into a normal template.

<template name="myComponent">
  {{> MyComponent}}
</template>

<template name="MyComponent">
  …
</template>

You would then point the router to render myComponent template.

MatejJan avatar Oct 21 '15 07:10 MatejJan

I suggest you use Flow Router. That one is the one I am using in my projects. See example app here.

I have some code made which would make Iron Router easier to use (route would be the same as component), but I have not yet fixed all the quirks.

mitar avatar Oct 21 '15 07:10 mitar

See #79.

mitar avatar Oct 21 '15 07:10 mitar