10

Is it possible to create a variable that is scoped to a template? This variable can be shared among the different helpers in the template, but does not exist outside of the template.

In this example below, how can game variable be shared between the 2 templates without repeating its definition? Initializing it using var makes it global which is not what I want. Thank you!

Template.userInfo.game = function() {
    var game = 'Angry Bird';
    return game + ' game';
};

Template.userInfo.score = function() {
    var game = 'Angry Bird';
    return game + ' score';
};

5 Answers 5

7

If anyone else stumbles across this and is using Meteor 1.0, here's how you can achieve this.

Template.name.onCreated(function(){
    this.data.variableName = "something";
});

Template.name.helpers({
    'helper' : function() {
        return Template.instance().data.variableName;
    }
});

This way the variable is scoped to the instance of the template that was created. I have a page that uses multiple instance of the same template so this was very useful.

EDIT:

So this worked perfectly for templates nested inside another template, but didn't work so well with the parent template. The data property wasn't holding values so I did some more research and found this in the example for Template.onCreated they have this.highlightedPicture = new ReactiveVar(null); so apparently it's fine to define new properties on your Template instance. I tried this in both scenarios and it works great with Template.instance().

Sign up to request clarification or add additional context in comments.

2 Comments

this.data is a readonly by official doc.
hi Shaded, I did indeed stumble across this (with Meteor now at 1.2.1) and hoped you had the solution for me but fear either things have changed or you didn't document the solution properly - basically you need to drop all references to .data, and just attach the variables to the template itself - see dweldon.silvrback.com/scoped-reactivity for a really good and easily digested example of how to make it work.
3

Why don't use

Template.foo.created = function() {
    this._someVariable = "some value"
}

Template.foo.someHelper = function() {
    return this._someVariable
}

Template.foo.events({
    "click #mylink": function(event, tmpl) {
        console.log(tmpl._someVariable)
    }
})

Your private _someVariable is not reactive it serves for options in this case. But you can wrap a Deps.Dependency() to get a private reactive Template's variables

3 Comments

The helper will not work - helpers have global scope.
Ahhhh, you are right! Don't we have a way to bind template instanse for any its helper?
The way to do this is to pass an argument to the helper from the HTML. So really once you need to do this kind of stuff you should probably be abstracting your models into classes.
2

From the docs: http://docs.meteor.com/#namespacing

Just declare it with a var and it will be file scope. Without the var it will be global scope.

var game = 'Angry Bird'; // File scope.
game2 = 'Angry Bird'; // App scope.

Comments

0

I had some issue to use autorun and variable scope, so maybe it will help someone :

Template.foo.someHelper = function() {
     return this._someVariable
}

Template.foo.events({
     "click #mylink": function(event, tmpl) {
          console.log(tmpl._someVariable)
      }
})
Template.foo.onRendered(function() {
      this._someVariable = "some value"
      this.autorun(function(templateInstance) {
            Collection.find({}).fetch(); // Autorun will be executed each time this collection has change (update, delete, insert)
            console.log(templateInstance._someVariable);
      }, this.templateInstance());
});

Comments

0

You could create it as a reactive var in the onCreated then return that variable in a helper. Wherever you set that variable it will automatically update the helper value. Here's an example:

Template.foo.onCreated(function() {
    this.yourVar = new ReactiveVar("");
    this.yourVar.set("initValue");
});

Template.foo.helpers({
    yourVar(){
        return Template.instance().yourVar.get();
    }
});

Template.foo.events({
    'click .btn': function (event) {
        template.yourVar.set($(event.target).val());
    }
});

Now you can call {{yourVar}} anywhere in your template and edit it's value as above.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.