Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to pass data to layout? #4

Closed
thearabbit opened this issue Mar 28, 2015 · 28 comments
Closed

how to pass data to layout? #4

thearabbit opened this issue Mar 28, 2015 · 28 comments

Comments

@thearabbit
Copy link

how to pass data to layout?

@vladshcherbin
Copy link

@yuomtheara I guess, you should make template helpers and pass data from there

@arunoda
Copy link
Contributor

arunoda commented Mar 28, 2015

@thearabbit
Copy link
Author

I checked example above, but don't understand.
Now I want to pass data to top: "header"

FlowLayout.render('layout1', { top: "header", main: "postList" });

Pl example.

@anyinfa
Copy link

anyinfa commented Mar 28, 2015

Same problem.

My current code is below:

  Router.route('/foos/editor/:_id', function() {
       var item = Foos.findOne({_id: this.params._id});
       this.render('foo_editor', {data: item});
  });

If I use FlowLayout, where should I pass DATA object?

Thanks a lot.

@arunoda
Copy link
Contributor

arunoda commented Mar 28, 2015

Inside your foo_editor template, there is template variable called data. (Since you've defined as it)

see:

<template name="foo_editor">
  Id of the document: {{data._id}}
</template>

@anyinfa
Copy link

anyinfa commented Mar 28, 2015

Dear arunoda,

Thanks your reply. I still make no sense.

My old render methods:

   Router.route('/foos/editor/:_id', function() {
          var item = Foos.findOne({_id: this.params._id});
          this.render('foo_editor', {data: item});
   });

Now change to FlowLayout:

   Router.route('/foos/editor/:_id', function() {
          // var item = Foos.findOne({_id: this.params._id});
          FlowLayout.render('layout1', { top: "header", main: "foo_editor" });
   });

I don't know how to pass 'var item...' object to the render method. Or, perhaps, I do this job incorrectly?

Thanks.

@arunoda
Copy link
Contributor

arunoda commented Mar 28, 2015

Okay. Now I got it.
You are trying to manage data in the route layer.

With flow, we don't provide easy ways for that. That's because it's wrong.
Handle data in the template layer in your app.
Let the router be just a router.

On Sat, Mar 28, 2015 at 7:47 PM anyinfa [email protected] wrote:

Dear arunoda,

Thanks you reply. I still make no sense.

My old render methods:

Router.route('/foos/editor/:_id', function() {
var item = Foos.findOne({_id: this.params._id});
this.render('foo_editor', {data: item});
});

Now change to FlowLayout:

Router.route('/foos/editor/:_id', function() {

// var item = Foos.findOne({_id: this.params._id});
FlowLayout.render('layout1', { top: "header", main: "foo_editor" });
});

I don't know how to pass 'var item...' object to the render method. Or,
perhaps, I do this job incorrectly?

Thanks.


Reply to this email directly or view it on GitHub
#4 (comment)
.

@anyinfa
Copy link

anyinfa commented Mar 28, 2015

I think I do this thing wrong way.
But, my template 'foo_editor' needs to know which item(or ._id) pass from path '/foos/editor/:_id' will to be edit.

@vladshcherbin
Copy link

@anyinfa
smth like this

Template.foo_editor.helpers({
    item: function () {
        return Foos.findOne({_id: Router.current().params._id});
    }
});

@anyinfa
Copy link

anyinfa commented Mar 28, 2015

@vladshcherbin

Thanks. This fixed my problem!

@thearabbit
Copy link
Author

Oh we can't pass data from the routee like iron-router.
Very thanks.

@smeijer
Copy link

smeijer commented May 21, 2015

@arunoda, I agree that the router should just be the router. But flow-layout ain't a router.

What if I wish to render different Template when clicking on a button, for example.

Template.myTemplate.events({
  'click .button': function(event, instance) {
     FlowLayout.render('details', 'main', { itemId: this.itemId  });
  }
});

Template.details.onCreated(function() {
  var id = this.data.itemId;
});

I wish to be able to render a different template, inside a region in the current layout.

@arunoda
Copy link
Contributor

arunoda commented May 21, 2015

Of course, you can use it however you like. But, if you using it inside flow-router, you should not(can't) use any collection data. Just pass params and fetch data from the template layer and render them.

@smeijer
Copy link

smeijer commented May 21, 2015

But if i'm not mistaken, that currently isn't possible with flow-layout. So are you suggesting to use Blaze.renderWithData for that part?

@Sewdn
Copy link

Sewdn commented Jun 3, 2015

I agree with @smeijer
Router should be just a router, but layout should be able to render templates to regions with a data-scope.
Please merge tomitrescak@462b411

thanks!

@sf-wind
Copy link

sf-wind commented Jul 9, 2015

I'm still confused. Does that mean every page need to have a different template? That seems quite a lot. For example, I have a "header" template. The structure of the header section in all pages are pretty much the same, but different "buttons" are put to different pages. The exact button in each page can be derived from the route alone.

I'd like to be able to have a common template for all headers, and then pass an array to specify the buttons to render based on the current page the user is in. How to achieve that with flow router?

Do I need to create a separate template for the header of each page? This seems a lot of work. Creating an array based on route is much simpler than creating separate templates.

Or do I still have a common template, but in the template helpers, conditionalize the "buttons" based on the route? It makes the rendering route aware. The code is not modularized as well.

Any other solution?

@serkandurusoy
Copy link

@sf-wind I'm trying to achieve the same kind of modularization. If we were able to pass arbitrary objects as a single parameter to the template, it would solve this problem. So what do you do to solve it?

In my case, I have multiple navigations, and I do something like:

// Route A
BlazeLayout.render('layout', {main: 'mainForRouteA', nav: 'navForRouteA'});
// Route B
BlazeLayout.render('layout', {main: 'mainForRouteB', nav: 'navForRouteB'})

while main for each route are completely different, nav are very similar and instead of maintaining two separate templates, I would have loved to be able to do this:

// Route A
BlazeLayout.render('layout', {main: 'mainForRouteA', nav: {template: 'nav', param: someObjectA}});
// Route B
BlazeLayout.render('layout', {main: 'mainForRouteB', nav: {template: 'nav', param: someObjectB}});

where someObjectA and someObjectB are not necessarily reactive. They are there for modularization and are simple key/value pairs that you want to pass into your template.

@serkandurusoy
Copy link

By the way, the documentation (readme) can be improved with the Notes on Passing Data section from https://kadira.io/academy/meteor-routing-guide/content/rendering-blaze-templates since the readme does not make it very obvious that you can pass data. At least an example would be great.

@sf-wind
Copy link

sf-wind commented Aug 17, 2015

@serkandurusoy For nav and main, I create a wrapper header template for each page, and then put the object as a helper function to the wrapper header. Not ideal, but solvable.

I have another issue with this, see: #30

For that, I ended up creating multiple layouts and handle the data passing from the nav and main in the layout template. So it doesn't really use dynamic template inclusion at all.

I think it is a big inconvenience that no data can be passed between the dynamically included templates provided by BlazeLayout.

@serkandurusoy
Copy link

Yes I agree. Sometimes it is just some static data and helps modularize templates. In my case I ended up passing in an arbitrary object as an extra parameter within the render function, and called necessary parts of that object from the data property of the dynamic template. Not very elegant, but seems (to me) better than maintaining cascaded templates.

@sf-wind
Copy link

sf-wind commented Aug 17, 2015

How to pass extra argument to the render function? I wasn't aware of that. Can you provide an example?

@serkandurusoy
Copy link

<template name="layout">
  <main>
    {{> Template.dynamic template=main}}
  </main>
  <aside>
    {{> Template.dynamic template=aside data=attrs.aside}}
  </aside>
</template>

<template name="asideTemplate">
  <ul>
    {{#each items}}
      <li>{{title}}: {{content}}</li>
    {{/item}}
  </ul>
</template>
var aside1Data = {
  items: [
    {title: 'title1', content: 'content1'},
    {title: 'title2', content: 'content2'}
  ]
}
BlazeLayout.render('layout', {main: 'mainTemplate', aside: 'asideTemplate', attrs: {aside: aside1Data}})

@sf-wind
Copy link

sf-wind commented Aug 24, 2015

Sweet. Just have time to take a look. I hope it can handle reactive data, but even it if doesn't, it is still very useful. Thanks.

@foobarbecue
Copy link

I really like VladShcherbin's method! Is this the accepted way of doing it? The documentation on this (how to e.g. set up a route & layout with flow-router and blaze-layout for a blog post display) is very confusing and there's a lot of useless / misleading stuff out there. I keep finding stuff about "anti-patterns" and nothing on how to actually do it correctly. Don't tell us about the anti-patterns, just tell us the patterns...

@foobarbecue
Copy link

Ok, I'm getting a feel for it... using FlowRouter.getParam('slug') instead of VladShcherbin's Router.current().params.slug as explained here and then I really don't need to do anything with data in the BlazeLayout call or the router.

@jhreis
Copy link

jhreis commented Nov 2, 2016

Just wanted to add, you can add additional params to the route param object (as arunodo pointed out). Just modify the param object on the route action method:

FlowRouter.route('/sub', {
    // ...
    action: function(params) {
        params['extraParam'] = "custom"
        BlazeLayout.render('layout', templates);
    }
})

Then just consume the params in template helpers and setup real data there (as pointed out previously).

@muralikrishna531
Copy link

I tried the following code to pass data to a template and receive it in onCreated() but i cannot access the data.

http://stackoverflow.com/questions/40841267/how-to-pass-the-data-to-a-template-using-blaze-layout-render

@adammoisa
Copy link

@jhreis how do you get the param after this? It doesn't seem to be working for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests