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

Custom block helper hides template instance #2923

Closed
lbergnehr opened this Issue Oct 27, 2014 · 6 comments

Comments

Projects
None yet
8 participants
@lbergnehr

lbergnehr commented Oct 27, 2014

When assigning properties to a template instance in the created method of a template and a helper of that template is invoked inside a custom block helper, which is in turn invoked inside the actual template, the template instance of Template.instance() will be that of the custom block helper and not of the "real" template. For example, consider this:

<template name="templateBug">
  {{#contentBlockTemplate}}
    <span>{{notVisibleString}}</span>
  {{/contentBlockTemplate}}
</template>

and notVisibleString is using Template.instance() to access a property of the template instance; then that instance will be that of contentBlock and not templateBug, which to me is counter intuitive and makes it difficult to use a custom block helper with assigning properties to a template instance in Template.myTemplate.created.

Steps to reproduce

Example project which visualizes this here: https://github.com/lbergnehr/meteor_template_content_block_bug

git clone https://github.com/lbergnehr/meteor_template_content_block_bug.git
cd meteor_template_content_block_bug
git checkout with_content_block
meteor

this will not show the intended text, whereas removing the content block will:

git checkout without_content_block
meteor
@dgreensp

This comment has been minimized.

Show comment
Hide comment
@dgreensp

dgreensp Nov 14, 2014

Contributor

You're right, this makes it pretty difficult to combine helpers that access the template instance with custom block helpers. It's a little scary to think about changing how Template.instance() works post 1.0, but I wonder if there's a quick fix.

Contributor

dgreensp commented Nov 14, 2014

You're right, this makes it pretty difficult to combine helpers that access the template instance with custom block helpers. It's a little scary to think about changing how Template.instance() works post 1.0, but I wonder if there's a quick fix.

@Sewdn

This comment has been minimized.

Show comment
Hide comment
@Sewdn

Sewdn Nov 15, 2014

I worked around this issue looking up the chain of parentView until you find the property you're looking for:

BlazeComponent.getFirstInstance = function(property){
  var comp = UI._templateInstance();
  if(comp[property])
    return comp[property];
  var view = comp.view.parentView;
  while(!view._templateInstance || !view._templateInstance[property]){
    view = view.parentView;
  }
  return view._templateInstance[property];
};

Sewdn commented Nov 15, 2014

I worked around this issue looking up the chain of parentView until you find the property you're looking for:

BlazeComponent.getFirstInstance = function(property){
  var comp = UI._templateInstance();
  if(comp[property])
    return comp[property];
  var view = comp.view.parentView;
  while(!view._templateInstance || !view._templateInstance[property]){
    view = view.parentView;
  }
  return view._templateInstance[property];
};
@tmeasday

This comment has been minimized.

Show comment
Hide comment
@tmeasday

tmeasday Dec 18, 2014

Contributor

The (simpler) workaround we've been using goes like this:

Template.X.created = function() {
  Template.X.current = this;
}

Template.X.helpers({
  foo: function() {
    // in here use Template.X.current rather than Template.instance()
  }
});

The big caveat is you can only have one instance of each template at once if you do this. But that's usually fine.

Contributor

tmeasday commented Dec 18, 2014

The (simpler) workaround we've been using goes like this:

Template.X.created = function() {
  Template.X.current = this;
}

Template.X.helpers({
  foo: function() {
    // in here use Template.X.current rather than Template.instance()
  }
});

The big caveat is you can only have one instance of each template at once if you do this. But that's usually fine.

@bensmeets

This comment has been minimized.

Show comment
Hide comment
@bensmeets

bensmeets Dec 18, 2014

Thanks for the tips. I use (i declare only 1 template per file) a simple "var" decleration on top of each file for now. Which seems to have the same effect. Thing is, this defeats the whole purpose of wanting something different than Session.get() in the first place, being able to use it on more instances at once :)

This is related I guess #2573

bensmeets commented Dec 18, 2014

Thanks for the tips. I use (i declare only 1 template per file) a simple "var" decleration on top of each file for now. Which seems to have the same effect. Thing is, this defeats the whole purpose of wanting something different than Session.get() in the first place, being able to use it on more instances at once :)

This is related I guess #2573

@johanbrook

This comment has been minimized.

Show comment
Hide comment
@johanbrook

johanbrook Jan 20, 2015

This is quite a pain actually. Any progress on this? I would love to have Template.instance() to guarantee to always return the template context of which the helper is attached to.

johanbrook commented Jan 20, 2015

This is quite a pain actually. Any progress on this? I would love to have Template.instance() to guarantee to always return the template context of which the helper is attached to.

@stubailo

This comment has been minimized.

Show comment
Hide comment
@stubailo

stubailo Jan 23, 2015

Contributor

#3545 is fixing this!

Contributor

stubailo commented Jan 23, 2015

#3545 is fixing this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment