Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Saturday, June 18, 2016

Accessing parent context in Meteor templates and template helpers

Accessing parent context in Meteor templates and template helpers


I'm running into a template context situation that I'm having a hard time finding a way around.


Here's the template in question:

{{#each votes}}      

{{question}}

    {{#each participants}}
  • {{email}}

  • {{/each}}
{{/each}}


And here's an example of a vote document:

{      _id: '32093ufsdj90j234',      question: 'What is the best food of all time?'      options: [          'Pizza',          'Tacos',          'Salad',          'Thai'      ],      participants: [          {              id: '2f537a74-3ce0-47b3-80fc-97a4189b2c15'              vote: 0          },          {              id: '8bffafa7-8736-4c4b-968e-82900b82c266'              vote: 1          }      ]  }  


And here's the issue...

When the template drops into the #each for participants, it no longer has access to the vote context, and therefore doesn't have access to the available options for each vote.

I can somewhat get around this by using the ../options handlebars path to jump back into the parent context, but this doesn't affect the context of the template helper, so this in Template.vote.is_selected_option refers to the current participant, not to the current vote or option, and has no way of knowing which option we are currently iterating through.

Any suggestions on how to get around this, without resorting to DOM manipulation and jQuery shenanigans?

This is a templating issue that has come up multiple times for me. We need a formal way of reaching up the template context hierarchy, in templates, template helpers, and template events.

Answer by AVGP for Accessing parent context in Meteor templates and template helpers


I don't know the formal way (if there is one), but to solve your issue, I would link the participants with the parent ID like this:

{      _id: "1234",      question: "Whats up?",      ...      participants: [        {          _id: "abcd",          parent_id: "1234",          vote: 0        }      ]  }  

and use this parent_id in helpers, events, etc. to jump back to the parent using findOne. That is obviously a sub optimal thing to do, but it's the easiest way that comes to my mind as long as there is no way of referencing the parent context. Maybe there is a way but it is very well hidden in the inner workings of Meteor without mention in the docs, if so: Please update this question if you find one.

Answer by zorlak for Accessing parent context in Meteor templates and template helpers


It's not particularly pretty, but I've done something like this:

          // and in the js:  Template.forLoop.helpers({      augmentedParticipants: function() {          var self = this;          return _.map(self.participants,function(p) {              p.parent = self;              return p;          });      }  });  

It's similar to the approach that AVGP suggested, but augments the data at the helper level instead of the db level, which I think is a little lighter-weight.

If you get fancy, you could try to write a Handlebars block helper eachWithParent that would abstract this functionality. Meteor's extensions to handlebars are documented here: https://github.com/meteor/meteor/wiki/Handlebars

Answer by danielsvane for Accessing parent context in Meteor templates and template helpers


It's a long shot, but maybe this could work:

{{#with ../}}    {{#each options}}      {{this}}    {{/each}}  {{/with}}  

Answer by Chet for Accessing parent context in Meteor templates and template helpers


This should make life easier.

// use #eachWithParent instead of #each and the parent._id will be passed into the context as parent.  Handlebars.registerHelper('eachWithParent', function(context, options) {        var self = this;      var contextWithParent = _.map(context,function(p) {          p.parent = self._id;          return p;      });        var ret = "";        for(var i=0, j=contextWithParent.length; i

Go ahead and change

p.parent = self._id;  

to whatever you want to access in the parent context.

Fixed it:

// https://github.com/meteor/handlebars.js/blob/master/lib/handlebars/base.js    // use #eachWithParent instead of #each and the parent._id will be passed into the context as parent.  Handlebars.registerHelper('eachWithParent', function(context, options) {      var self = this;      var contextWithParent = _.map(context,function(p) {          p.parent = self._id;          return p;      });        return Handlebars._default_helpers.each(contextWithParent, options);  });  

This works :) with no error

Answer by opyh for Accessing parent context in Meteor templates and template helpers


It seems since Spacebars (Meteor's new template engine), you have access to the parent context within {{#each}} blocks using ../.

In Meteor 0.9.1, you can also write a helper and use Template.parentData() in its implementation.

Answer by Jan Curn for Accessing parent context in Meteor templates and template helpers


Simply register a global template helper:

Template.registerHelper('parentData',      function () {          return Template.parentData(1);      }  );  

and use it in your HTML templates as:

{{#each someRecords}}    {{parentData.someValue}}  {{/each}}  

======= EDIT

For Meteor 1.2+, you shold use:

UI.registerHelper('parentData', function() {    return Template.parentData(1);  });  

Answer by oskare for Accessing parent context in Meteor templates and template helpers


I was stuck in a similar way and found that the Template.parentData() approach suggested in other answers currently doesn't work within event handlers (see https://github.com/meteor/meteor/issues/5491). User Lirbank posted this simple workaround:

Pass the data from the outer context to an html element in the inner context, in the same template:

{{#each companies}}    {{#each employees}}      Do something    {{/each}}  {{/each}}  

Now the company ID can be accessed from the event handler with something like

$(event.currentTarget).attr('companyId')  

Answer by BGbhavesh for Accessing parent context in Meteor templates and template helpers


"click .selected":function(e){      var parent_id = $(e.currentTarget).parent().attr("uid");      return parent_id    },
                                          {{#each all_req_doc}}                                                  
{{/each}}


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.