javascript - how to make a meteor template helper re-runrender after another template has rendered? - Stack Overflow

I have a template helper called {{renderNav}} in a template Nave.g.Template.Nav.renderNavand within tha

I have a template helper called {{renderNav}} in a template Nav

e.g.

Template.Nav.renderNav

and within that helper function I want to parse the rendered output of another helper within a different template

For example the helper

Template.contentWindow.content

which provides the html for

{{content}}

and my renderNav helper wants to part the html that replaces {{content}} to generate the html for

{{renderNav}}

how would I do this? right now the {{renderNav}} helper executes for or runs more quickly and so it is unable to parse the html that replaces {{content}}

@Hugo - I did the following in my code as you suggested

Template.contentWindow.rendered = function() {
    debugger;  
    return Session.set('entryRendered', true);
};

Template.Nav.renderNav = function() {
    debugger;
    var forceDependency;
    return forceDependency = Session.get('entryRendered');
};

When I run it, the debugger first stops when executing the renderNav helper. (Which makes sense with what I am seeing in terms of the race condition). Then contentWindow renders and I hit the breakpoint above the Session.set('entryRendered', true). But then the renderNav doesn't run again as you suggest it should. Did I misinterpret or incorrectly implement your suggestion?

I have a template helper called {{renderNav}} in a template Nav

e.g.

Template.Nav.renderNav

and within that helper function I want to parse the rendered output of another helper within a different template

For example the helper

Template.contentWindow.content

which provides the html for

{{content}}

and my renderNav helper wants to part the html that replaces {{content}} to generate the html for

{{renderNav}}

how would I do this? right now the {{renderNav}} helper executes for or runs more quickly and so it is unable to parse the html that replaces {{content}}

@Hugo - I did the following in my code as you suggested

Template.contentWindow.rendered = function() {
    debugger;  
    return Session.set('entryRendered', true);
};

Template.Nav.renderNav = function() {
    debugger;
    var forceDependency;
    return forceDependency = Session.get('entryRendered');
};

When I run it, the debugger first stops when executing the renderNav helper. (Which makes sense with what I am seeing in terms of the race condition). Then contentWindow renders and I hit the breakpoint above the Session.set('entryRendered', true). But then the renderNav doesn't run again as you suggest it should. Did I misinterpret or incorrectly implement your suggestion?

Share Improve this question edited Jul 11, 2013 at 14:05 funkyeah asked Jul 11, 2013 at 3:22 funkyeahfunkyeah 3,1946 gold badges33 silver badges48 bronze badges 7
  • Not sure what your are trying to do. Suppose content ends before renderNav. How do you access content html from within renderNav? – Xyand Commented Jul 11, 2013 at 7:02
  • I am trying to access the html that the content helper renders from within the renderNav helper. Which is causing a sort of race condition where renderNav executes first and is not able to access the DOM HTML that the content helper puts out. – funkyeah Commented Jul 11, 2013 at 14:07
  • Although you can hack it, it sounds like you're doing something the wrong way. Why do you need the DOM of an template you rendered yourself? You should have all the data you need in renderNav context. Maybe you could add some renderNav code to explain how it uses content DOM segment. – Xyand Commented Jul 11, 2013 at 14:43
  • you are probably correct that I'm not doing it a very meteoric way... a code fragment would not be very descriptive in this case but the explanation is... the {{content}} helper renders as a page with any number of headings in it (H1,H2,H3,etc...); the renderNav helper is part of a sidebar template that parses the content for those headings and effectively builds a table of contents --- so i don't know how I would pass the html that the content helper produces to the renderNav helper – funkyeah Commented Jul 11, 2013 at 14:56
  • See the update to my answer. Does it help? – Hubert OG Commented Jul 11, 2013 at 15:45
 |  Show 2 more ments

2 Answers 2

Reset to default 4

You need a dependency in the template that you want to rerun. There are few possibilities, depending on what data you want to get.

For example, you can set a reactive marker in the content template that will notify renderNav that it's done with drawing.

Template.contentWidnow.rendered = function() {
    ...

    // Set this on the very end of rendered callback.
    Session.set('contentWindowRenderMark', '' +
        new Date().getTime() +
        Math.floor(Math.random() * 1000000) );
}


Template.renderNav.contentData = function() {
    // You don't have to actually use the mark value,
    // but you need to obtain it so that the dependency
    // is registered for this helper.
    var mark = Session.get('contentWindowRenderMark');

    // Get the data you need and prepare for displaying
    ...
}

 


 

With further information you've provided, we can create such code:

content.js

Content = {};
Content._dep = new Deps.Dependency;

contentWindow.js

Template.contentWidnow.rendered = function() {
    Content.headers = this.findAll(':header');
    Content._dep.changed();
}

renderNav.js

Template.renderNav.contentData = function() {
    Content._dep.depend();
    // use Content.headers here
    ...
}

If you want the navigation to be automatically rebuilt when contentWindow renders, as Hubert OG suggested, you can also use a cleaner, lower level way of invalidating contexts:

var navDep = new Deps.Dependency;

Template.contentWindow.rendered = function() {
    ...
    navDep.changed();
}

Template.renderNav.contentData = function() {
    navDep.depend();

    // Get the data you need and prepare for displaying
    ...
}

See http://docs.meteor./#deps for more info.

If, on the other hand, you want to render another template manually, you can call it as a function:

var html = Template.contentWindow();

The returned html will not be reactive. If you need reactivity, use:

var reactiveFragment = Meteor.render(Template.contentWindow);

See the screencasts at http://www.eventedmind./ on Spark and reactivity for details on how this works.

UPDATE

To add a rendered fragment to your DOM:

document.body.appendChild(Meteor.render(function () {
    return '<h1>hello</h1><b>hello world</b>';
}));

You can also access the rendered nodes directly using the DOM API:

console.log(reactiveFragment.childNodes[0]);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743868141a4520940.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信