Slicky
Slicky

Reputation: 97

Meteor template not updating on changed data

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 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!

Upvotes: 1

Views: 1096

Answers (2)

iamhimadri
iamhimadri

Reputation: 552

Do you have idea about reactive-var in meteor (Meteor Doc) or you can also use Session instead of reactive-var (ReactiveVar is similar to a Session variable)

Have a look at changes as per your code.

Here is the template(.html)

<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">{{getAttributeValue}}</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 helpers for your template(.js)

Template.attributeStepper.created = function(){
    this.attributeValue = new ReactiveVar(parseInt(this.data.attributeValue));
}

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

Template.attributeStepper.events({
    'click .btn-value-inc' : function(event, tmpl) {
        tmpl.attributeValue.set(tmpl.attributeValue.get()+1)
    },

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

Template.attributeStepper.created = function(){...} method called before your template's logic is evaluated for the first time.

Upvotes: 1

Tom Freudenberg
Tom Freudenberg

Reputation: 1367

There is nothing wrong but also nothing reactive in your code. For the attributeValue you should use a template based ReactiveVar which is created at the onCreate Event

Template.attributeStepper.onCreated(function() {
  if (! _.isUndefined(this.data.startingValue))
    this.attributeValue = new ReactiveVar(Number(this.data.startingValue));
  else
    this.attributeValue = new ReactiveVar(0);
})

You can use some initialValue from Template as you like

See complete example at the MeteorPad I created for you.

http://meteorpad.com/pad/Zw7YnnW57uuGKcu3Q/MultipleTemplateUsage

This should solve your question

Cheers Tom

Upvotes: 1

Related Questions