Meteor template not updating on changed data


#1

I’m currently building a nifty little ‘talent point distributor’ view, similar to what popular RPG games offer. I didn’t want a huge wall of HTML code for all the buttons and textboxes, so I created a template to which I pass two parameters:

  • the name of the stat I want to alter
  • the initial value of the stat

The template renders correctly, and I notice that when I log the results to the console, the variable seems to be changed correctly. However, the displayed value does not change and will always stay at 0.

Here is the template itself:

<template name="attributeStepper">
  <div class="row" style="margin: 1em;">
    <div class="col-sm-3 col-md-2">
      <h4>{{toUpper attribute}}</h4>
    </div>
    <div class="col-sm-6 col-md-4">
      <div class="btn-group" role="group">
        <button type="button" class="btn btn-default btn-value-dec">
          <span class="glyphicon glyphicon-chevron-down"></span>
        </button>
        <button type="button" class="btn btn-default disabled">{{attributeValue}}</button>
        <button type="button" class="btn btn-default btn-value-inc">
          <span class="glyphicon glyphicon-chevron-up"></span>
        </button>
      </div>
    </div>
  </div>
</template>

Here is the helper I defined for the template:

Template.attributeStepper.helpers({
  toUpper : function(str) {
    return str.substring(0, 1).toUpperCase() + str.substring(1);
  }
})

Template.attributeStepper.events({
  'click .btn-value-inc' : function(event, tmpl) {
    tmpl.data.attributeValue ++;

  },

  'click .btn-value-dec' : function(event, tmpl) {
    tmpl.data.attributeValue --;
  }
});

And this is how I call the templates from the actual view:

<div class="panel panel-default">
      <div class="panel-heading">
        <h3 class="panel-title">Attributes</h3>
      </div>
      {{ >attributeStepper attribute="strength" attributeValue="0"}}
      {{ >attributeStepper attribute="courage" attributeValue="0"}}
      {{ >attributeStepper attribute="intelligence" attributeValue="0"}}
      {{ >attributeStepper attribute="agility" attributeValue="0"}}
      {{ >attributeStepper attribute="dexterity" attributeValue="0"}}
      {{ >attributeStepper attribute="intuition" attributeValue="0"}}
      {{ >attributeStepper attribute="charisma" attributeValue="0"}}
    </div>

I hope you can make any sense out of this and tell me what I’m doing wrong, because I feel like I’m not following the mindset behind Meteor correctly yet.

Cheers!


#2

You need some kind of reactive content, for example reactive variable to re-render template when it changes.
So for example create one in http://docs.meteor.com/#/full/template_onRendered based on provided attribute (which will just define default value) and work with that reactive variable.
Helper will than re-run as soon as you change it.


#3

Is it really necessary to fiddle around in the DOM? I also read there was a Meteor package which allowed you to create reactive variables yourself as you need them, wouldn’t this be a better approach?


#4

Well,
where is better spot to create that reactive variable from package, than in template initialisation, so in onRendered handler.
Dont forget to scope it only for that template, so use that
var myHappyVariable = … //dont forget that "var"
I dont have example to paste here, as I am just checking from random pc.

It is not in DOM, it is in data/js part of template.

Have fun