简体   繁体   中英

New to Meteor and helper function is not working

I am learning meteor and I cannot get my helper function to return some static text.

<head>
    <title>LeaderBoard</title>
</head>

<body>
    <h1>Leaderboard</h1>

        <p>{{player}}</p>
</body>

in JS

if(Meteor.isClient){
    Template.leaderboard.helpers({
        player: function(){
        return "text";
        }
            });

}

This only returns the Leaderboard header

UPDATE: changed to: LeaderBoard

<body>
    <h1>Leaderboard</h1>

        <p>{{player}}</p>
</body>
<template name="leaderboard">
    {{player}}
</template>

and JS is still the same and it still does not work

So, there are few mistakes you made. Let's deconstruct it.

What is a template?

A template is a piece of code that renders into DOM and can be manipulated using helpers, events and such. For you to use any template, there has to exist one. They can either be put into your app from packages or made by yourself. In this particular case, you're looking for the latter.

To define a template, pick any HTML file or create a new one and define it in HTML way:

<template name="theTemplate">
  Hello, I am the template.
</template>

So now you can inject this template wherever in the DOM you want, using this syntax:

<body>
    <h1>My super app</h1>
    <div>{{> theTemplate}}</div>
</body>

It will render into

<body>
    <h1>My super app</h1>
    <div>
        Hello, I am the template.
    </div>
</body>

or, in fact, something a bit uglier since Meteor preserves all the indentation and stuff.

How can I put changeable text into the template?

You're already right that you need helpers for that. A helper is a function that returns an Object (be it String, Number, etc.) which is being injected as is, as if it was document.write d.

Helpers for any template are defined in this way:

Template.theTemplate.helpers({
    coolestString: function () {
        return 'I am the coolest string put by a helper.';
    }
});

Note that Template object contains theTemplate property. It happened exactly after Meteor picked up your template definition and then stored it into an object with helpers method (and a bunch of other useful methods, too).

If you remove theTemplate template definition (aka HTML), the Template object will not have its theTemplate property, and the whole thing will throw a TypeError since you try to access a property of undefined .

How do I put values returned by helpers into the template?

Simply use {{ ... }} syntax. Say, you have a helper coolestString and you need to fetch value from it, whatever it is, and put into h1 tag:

<template name="theTemplate">
    <h1>{{ coolestString }}</h1>
</template>

Note the difference between {{> ...}} and {{ ...}} . The former inject a template, the latter inject a value from current context; template's helpers stay within its root context (or just forget it if you don't understand contexts yet).

So, what should I do to use template in my app?

To make a conclusion,

  1. Define a template.
  2. Optionally, define its helpers. Each helper should return a string, a number, an array or an object.
  3. Access helpers' values within the template using {{ ... }} syntax.
  4. Inject the template into your document using {{> ...}} syntax.

That's it.

Okay, show me the whole code!

In myCoolestApp.html ,

<body>
    {{> theTemplate}}
</body>

<template name="theTemplate">
    {{ coolestAppName }}
</template>

And in myCoolestApp.js ,

if (Meteor.isClient()) {
    Template.theTemplate.helpers({
        coolestAppName: function () {
            return 'My super cool app!';
        }
    });
}

Done!

But what if I want to omit template?

In general, a helper by definition belongs to some template, so the hierarchy of injection is the body, then the template, then the helper. But it is possible to inject a helper right into document body and omit intermediary template. You do so with Template.registerHelper method:

Template.registerHelper('theHelper', function () {
    return 'I am helper'; // add some logic here and see how it works; hint: reactively.
});

What you do then is just put it into your document:

<body>
    {{ theHelper }}
</body>

which gets rendered to

<body>
    I am helper
</body>

The principle behind Template.registerHelper is DRY, don't repeat yourself. Sometimes you need to provide exactly same data to more than one template, so at first you would think you have to copy helpers code. But this method helps avoid unnecessary repetition.

You can use more complex objects, covered with more complex logic, this way, or you can even put Mongo collections into the document directly.

Option 1

In case you dont have multiple pages/screens for your app. Edit your template html like this.

   <head>
     <title>LeaderBoard</title>
   </head>

 <body>
     <h1>Leaderboard</h1>

    {{> leaderboard}}
  </body>
  <template name="leaderboard">
    {{player}}
  </template>

PS:- {{player}} refers to the template helper "player" and {{> leaderboard}} refers to a template ( This is handlebar syntax ).

Option2 : Your template should look like this.(Assuming you have multiple pages/screens for you app - it would be better if you use some kind of router)

  1. A main layout page - call it master.html

      <head> <title>LeaderBoard</title> </head> <body> </body> 
  2. A template named leaderboard. call it leaderboard.html

      <template name="leaderboard"> {{player}} </template> 
  3. Then your helper with the same code that you provided in the question.

This should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM