How do I reactively create a child template with data?


#1

Hello,

I’m trying to instantiate a child template the changes its content depending on the given data.

e.g

<template name="parent">
{{>child aReactiveParameter}}
</template>

I see two possibilities here of expected behavior. child is :

  1. recreated with aReactiveParameter in the data context (Blaze.renderWithData -> Blaze.remove -> Blaze.renderWithData)

  2. rerendered, thus triggering child.onRendered

This, however, is not the case and I found myself forced to do option 1. manually. Is there a way to do so automatically? I tried autorun (in both parent and child) to no avail :frowning:


#2

http://docs.meteor.com/#/full/template_dynamic


#3

For example, if there is a template named “foo”, {{> Template.dynamic
template=“foo”}} is equivalent to {{> foo}} and
{{#Template.dynamic template=“foo”}} … {{/Template.dynamic}}
is equivalent to {{#foo}} … {{/foo}}.

That’s what I did and it doesn’t work :frowning:


#4

well, hard to comment when u did not paste any relevant code.
if u want to pass parameter do it like
{{>child parameter=aReactiveParameter}}
and in child template access it as
{{parameter}}

Or read https://www.discovermeteor.com/blog/meteor-components-template-controller-pattern/


#5

Here’s a pretty example pad. Click the button in the parent to increment the parameter being passed to the child. The child should call a function each time there was an update --> How does one do that in a clean fashion?

I found that adding the function as a helper and using the helper did the trick, but that’s… ugly. It means I need to have a useless element in my view + the code is no longer separated from the view.


#6

http://meteorpad.com/pad/QhvhRCST9MspxddjE/Copy%20of%20Parents%20adding%20to%20children


#7

I think this might help you:

Template.parent.onCreated(function(){
 this.templateName=new ReactiveVar('someDefaultTemplateToLoad');
  this.reactiveParm=new reactiveVar(null);
});

Template.parent.helpers({
 getTemplateName=function(){ 
  return Template.instance().templateName.get();
 },
  somereactiveVar:function(){
   return Template.instance().reactiveParm;

   getParamsData:function(){
       return Template.instance().reactiveParm.get();
    }
 });

parentTemplate.html
{{> Template.dynamic template=getTemplateName parms=somereactiveVar}}
<span> {{getParamsData}} </span>

this will load the template dynamically according to the reactive Variable passed into templateName

we might also need to change the reactive parameter from the child template for eg ,

 Template.child.onRendered(function(){
     Template.instance.data.params.set('rendered');
   });

this will change the text in the span tag once the child template is rendered


#8

That works. I’m quite curios to know how? Why does the autorun work in onRendered and not in onCreated?

Run a function now and rerun it later whenever its dependencies
change. Returns a Computation object that can be used to stop or observe the
rerunning.

How does it know which dependencies it has?


#9

A brief introduction to Tracker, which is the underlying technology behind this is in the docs. For more detail, check out the Meteor Manual - note this still refers to Tracker’s old name, Deps. For chapter and verse, the code for Tracker is compact and well annotated. Read in conjunction with the code for some of the reactive data objects - ReactiveDict and ReactiveVar are small and easy to grok.