简体   繁体   中英

Switch in Meteor template helper

I have a template with a table created by iterating over an array of user selected companies, which are stored, by ticker symbol, in a document attribute called selections . I show different values associated with each company, depending on a different user selection, called metric .

I am having trouble writing a helper with the if/else statement required to change the value depending on the user selection. With the code below, headingNum and headingDen are showing properly. So is companyName which is associated with an individual selection. If I replace valuationNum with this.reported.capTable.enterpriseValue , the correct value appears. But I cannot get it to appear when using the helper.

<template name="Table">
    <div>
        <table>
            <thead>
                <tr>
                    <th>Company</th>
                    <th>{{headingNum}}</th>
                    <th>{{headingDen}}</th>
                </tr>
            </thead>
            <tbody>
                {{#each selections}}
                    <tr>
                        <td>{{companyName}}</td>
                        <td>${{valuationNum}}</td>
                        <td>${{valuationDen}}</td>
                    </tr>
                {{/each}}
            </tbody>
        </table>
    </div>
</template>

JS file

var metric = this.metric;
var period = this.period;
Template. Table.helpers({
    selections: function () {
        var selected = this.selections;
        return Companies.find({ticker: {$in: selected}})
    },
    headingNum: function () {
        switch (metric) {
            case "A":
                return "EV";
                break;
            case "B":
                return "Price";
                break;
            default:
                return "EV"
        }
    },
    valuationNum: function() {
        switch (metric) {
            case "A":
                return this.reported.capTable.enterpriseValue;
                break;
            case "B":
                return this.reported.capTable.lastClose;
                break;
            default:
                return ""
        }
    }
});

I tried breaking out the {{#each}}{{each}} block into a new template to see if it would help with the data context but no luck (and it messes up the table).

Am I writing these helpers correctly? I also receive an error message in the JS file saying reported is an unresolved variable even though that is the correct path.

Thank you.

EDIT:

This helper works, not sure why the other doesn't:

headingNum: function () {
    var metric = this.metric;
    switch (metric) {
        case "EV/EBITDA":
            return "EV";
            break;
        case "Price/Earnings":
            return "Price";
            break;
        default:
            return ""
    }
}

Meteor's template is built on blaze , which is reactive by design. This means that the template will only re-render when the data dependency values change. In this example, only when you modify Companies . However, when you modify the value of metric , the template will not re-render, which is why you are not seeing the change you expect.

The reactive way of achieving your goal is actually putting in the metric switch logic right inside the template:

{{#each selections}}
    <tr>
        <td>{{companyName}}</td>
        {{#if metricA}}
        <td>${{reported.capTable.enterpriseValue}}</td>
        {{else}}
        <td>${{reported.capTable.lastClose}}</td>
        {{/if}}
        <td>${{valuationDen}}</td>
    </tr>
{{/each}}

Inside your JS:

Template. Table.helpers({
    metricA: function() {
        return this.metric == 'A';
    }
})

Just having a quick browse over your code, just a few things.

You have set the metric and period variables at the window scope - not the template scope. This is why your unable to access the metric variable within your helper. To fix, just remove the var from where you initially create the metric variable. This however, is not a good way to manage the scoping and variable management.

I would say to make this really effective, you want to have a helper and event handler to track the getting and setting of the metric reactively (reactive-var package helps for this)

Setup the metric reactive variable

Template.Table.created = function() {
  this.metric = new ReactiveVar();                                      
}

Get the Metric

Template.Table.helpers({
  getMetric: function() {
    return this.metric.get();
  }
})

Set the Metric

Template.Table.events({
  'click .setMetric': function(event, template) {
    event.preventDefault();
    var metric = $(event.target).data('metric');
    if(metric) template.data.metric.set(metric);
  }
});

Then using these, as a strategy you could simply have a helper for your headings and values - determining the metric on demand and restricting it.

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