Closed kakadais closed 3 years ago
if you're using Blaze, you could combine watchPathChange
or triggersEnter
with Tracker.afterFlush
to run after Blaze has rendered all pending templates?
In both cases, it runs before all the templates onRendered run in my test. So Dom control is missing sometimes.
I think this is a kind of old school question, and I still don't get the best solution. Probably I could miss something important.
Hopefully, @dr-dimitru has the answer~ ;)
Hello @kakadais,
How do you render templates?
In case if you're using this.render()
method you can pass a callback as a last argument.
Providing more details on what you're actually trying to accomplish would help to find a solution.
As you said get a callback after all templates are rendered, -- top parent blaze template should fire onRendered callback only after all nested templates are rendered as well, isn't it 🤔?
@dr-dimitru Sorry for the lack of information.
I've added details on the question, and I think I could say this is basically about lazy-loading for dynamic blaze things, am I right?
@kakadais
this.render()
and {{> yield}}
for templatingthis.render()
callback to catch the moment when template fully rendered (including nested templates)FlowRouter.watchPathChange()
as you can guess from its name made to catch an event of URL change, and not related to rendering templates
@dr-dimitru If I want to call the callback for every template, do I need to add the callback to all template's this.render() function? I just want to keep my code simple, so I am trying to find an event for all.
Could I use the layout template's this.render() or something like that? I understand that nested templates included on parent template's this.render(), but still I have multiple templates as a parent and url path. So I don't want to add the same callback for all parent templates.
Ex> to be a clear explanation with poor english ;) If I have template A and B, the url would be mysite/A and mysite/B. And each template uses it's own FlowRouter.route() setting and this.render(). I don't want to add the callback for A/B... multiple times. Am I missing something?
@kakadais sorry, I don't get it. Could you paste your FlowRouter.route()
definitions?
You use this.render()
only once per route inside action
hook. The reat should be done in Template#onRendered
callback. Callback passed into this.render()
would be the one which runs after template (including all nested templates) rendered, — I assume this is what you were looking for in your original post (original question)
Sorry for my poor explanation, or could be my misunderstanding. I added an additional explanation on my original question like below.
Suppose that I have five 5 dynamic templates in the layout and each template has the own route and path by different url path, so if a user clicks the link and changes the path, the dynamic template just rendering on its position in the layout.
In this case, I have to add the foo()
to all 5 templates this.render()
in their callback to run the foo() every single time after rendering.
If I add the foo()
to 'layout' template's this.render()
in callback,
it is working at the first rendering of 'layout' template,
but the foo() is not running on the next path changing by user's click action.
(dynamic template is changing but the layout's this.render()
is not working cause it's already been rendered before)
So what I want to do is,
run the foo()
every single time when the dynamic path changing,
without adding the foo()
to all callback in the dynamic template's this.render()
.
Declare once and run everytime when the path chaning after rendering to avoid code mess and repeats.
@kakadais Seems like you're looking for { conf: { forceReRender: true } }
option. Let me know if it helps
@kakadais if forceReRender
isn't what you're looking for, please speak code and post your route definition.
@dr-dimitru I believe this question could have a simple answer ;) I've added Code example. force-rerender wouldn't be my option, because I don't want to rerender every time.
FlowRouter.route '/notice',
name: 'notice'
action: ->
@render 'layout', 'notice', ->
foo()
FlowRouter.route '/news',
name: 'news'
action: ->
@render 'layout', 'news', ->
foo()
I just want to do the same thing without foo() repeats, because there will be many templates and will be added.
FlowRouter.route '/layout',
name: 'layout'
action: ->
@render 'layout', ->
foo()
This is not working on dynamic template changing.
Thanks a lot always.
I just want to do the same thing without foo() repeats, because there will be many templates and will be added.
How you planning switch dynamic template in this FlowRouter.route '/layout',
case? Still didn't get what are you trying to accomplish
@kakadais Id do something like this:
mycallback = ->
FlowRouter.route '/notice',
name: 'notice'
action: ->
@render 'layout', 'notice', mycallback
FlowRouter.route '/news',
name: 'news'
action: ->
@render 'layout', 'news', mycallback
Looks like correct usage to me. You can even create an array and iterate over it to register similar routes
Hey @kakadais,
Any progress on this one? Here's a recent example on the similar use-case
I've run a function everytime when its needed such as your proposal. I still have some curious there would be a better way to apply this, but couldn't make it. The case was so specific for my case, so this would be better to be closed. Thanks-
What I want
Run a function always after all templates onRendered with FlowRouter way. (not the way of jQuery or direct dom control)
Ex> In the case of dynamic templete with blaze-layout, we could have a lot of nested templates.
And I need to run some code foo() once to control Dom after rendering all, always. I could accomplish this run the foo() in all of the dynamic templates, but seems like a bad idea.
The foo()
is simple jQuery Dom handling for some reason.Additional Example to explain
Suppose that I have five 5 templates and each template has the route by different url path, so if a user clicks the link and changes the path, the dynamic template just rendering on its position in the layout.
In this case, I have to add
the foo()
to the 5 templatesthis.render()
in their callback to run the foo() every single time after rendering.If I add the
foo()
to 'layout' template'sthis.render()
in callback, it is working at the first rendering of 'layout' template, but the foo() is not running on the next path changing by user's click action. (dynamic template is changing but the layout's this.render() is not working cause it's already been rendered before)So what I want to do is, run the foo() every single time when the dynamic path changing, without adding the foo() to all callback in the dynamic template's this.render().
Declare once and run everytime when the path chaning after rendering to avoid code mess and repeats
Codes Example
I just want to do the same thing without foo() repeats.
This is not working on dynamic template changing.
watchPathChange way
https://github.com/VeliovGroup/flow-router/blob/master/docs/api/watchPathChange.md
This was the best approach in a document that I found. but I think there would be a better way to do this with the flow-router way.
Result of on first load or full reload the page
autorun triggers autorun something layout
The foo() in 'autorun' fired faster than 'something', and 'triggers' is even faster.
Result of on changing path
triggers autorun publication
The foo() is faster still. But, in this case, the dom control that I want is worked. (Actually this part is more tricky for me.) Anyway, I think that this is not the best idea.
So What I want Again
is run the foo() after the last template rendered.