Check for equality in Spacebars?

2019-01-18 03:29发布

问题:

I am trying to do what I think should be a very simple task, but have been failing to do so in the past hour. I want to select a select option by default if the user property matches the value.

<select name="myName">
  {{#each addKeys myTable}} <!-- addKeys creates variables for keys and values -->
    <option value="{{key}}" {{#if currentUser.property === key}}selected="selected"{{/if}}>{{value}}</option>
  {{/each}}
</select>

Now I thought this was straightforward enough to be implemented. But it turns out that Spacebars do not allow conditional operators other than the negation exclamation mark, so equal signs are out of question. I then tried something horrible for the sake of trying:

In template myTemplate:

<select name="myName">
  {{#each addKeys myTable}}
    <option value="{{key}}" {{isSelected currentUser.property key}}>{{value}}</option>
  {{/each}}
</select>

In mytemplate.js :

Template.myTemplate.helpers({
  isSelected: function(v1, v2) {
    if (v1 === v2)
      return "selected=\"selected\"";
    return '';
  }
});

Not only is this code terrible, terrible to look at, it does not work:

Exception in Meteor UI: String contains an invalid character

I don't understand why something that simple seems so impossible to achieve. Am I missing something there?

回答1:

Try this:

In your template:

<option value={{key}} selected={{isSelected currentUser.property key}}>

Then have your helper return a boolean.

More on the topic here: https://github.com/meteor/meteor/wiki/Using-Blaze#conditional-attributes-with-no-value-eg-checked-selected



回答2:

Here's an overview of {{#if}} statements in Spacebars

Property

Of course the simplest possible implementation is when the scoped object has a property that evaluates to a boolean

For example if you had:

var item = {
  text: 'hello',
  checked: false
};

Then you could evaluate an if block like this:

class="{{#if checked}}checked{{/if}}"

Function

We could also evaluate a function here as well. Rather than add a function to the item, we can add a function to the helper and it will inherit the datacontext of the item being passed to it. So if we had the following helper:

Template.item.helpers({
    saysHi: function() {
      return this.text === "hi";
    }
});

Then we could run the following code:

<template name="item">
   {{text}}
   {{#if saysHi}} - Hi Back {{/if}}
</template>

Note: The helper's implementation can access the current data context as this.

Function with Parameters

You can also pass any number of parameters to helper functions like this:

Template: {{frob a b c verily=true}}
Helper Call: frob(a, b, c, Spacebars.kw({verily: true}))

When applied to our if block, we can do the following:

{{#if equals owner currentUser._id}}
    <button class="delete">&times;</button>
{{/if}}

Then add equals to our template helper like this:

Template.item.helpers({
    equals: function(v1, v2) {
        return (v1 === v2);
    }
});

Universal Helpers

Since this is a generic method that could be useful anywhere, we should add it to every template instead of recreating it.

Note: To create a helper that can be used in any template, use Template.registerHelper.

Template.registerHelper('equals',
    function(v1, v2) {
        return (v1 === v2);
    }
);

Here's a working Demo in MeteorPad that includes one of each of the types of IF's constructed here



回答3:

Although spacebars does not support equality, this method works to check for equality

you can use something like this

{{#if chkeq variable value}}

example

{{#if chkeq applicationStatus "Draft"}}

at least it worked for me

where chkeq is a global helper, which goes something like this

chkeq:function(a,b){
    if(a==b){
      return true;}
else return false;
}