542 votes

Opérateur logique dans un handlebars.js {{#if}} conditionnelle

Est-il un moyen de guidon JS d’incorporer des opérateurs logiques dans l’opérateur conditionnel handlebars.js standard ? Quelque chose comme ceci :

Je sais que je pourrais écrire mon propre aide, mais je tiens à vous assurer que je ne suis pas réinventer la roue.

569voto

Nick Kitto Points 1855

C’est possible de « tricher » avec une aide de bloc. Cela va probablement contre l’idéologie du peuple qui a développé le guidon.

Vous pouvez ensuite appeler le programme d’assistance du modèle comme ceci

501voto

Jim Points 544

Prenant l’un pas plus loin. Cela ajoute l’opérateur de comparaison.

Utiliser dans un template comme ceci :

Version de Script cafée

93voto

bentael Points 409

la prise de ce une montée d'un cran, pour ceux d'entre vous qui vivent sur le bord.

résumé: https://gist.github.com/akhoury/9118682 Démo: http://jsbin.com/jeqesisa/7/edit?html,js,sortie

Guidon Helper: {{#xif EXPRESSION}} {{else}} {{/xif}}

une aide pour exécuter une instruction SI avec toute expression

  1. L'EXPRESSION est correctement Chaîne d'échappement
  2. Oui vous avez BESOIN pour échapper correctement les littéraux de chaîne ou tout simplement alterner les guillemets simples et doubles
  3. pour accéder à toute fonction ou une propriété, vous devez utiliser window.functionName() au lieu de simplement en functionName()
  4. cet exemple suppose que vous avez passé ce contexte, à vos guidon template( {name: 'Sam', age: '20' } ), avis, age est string, juste pour afin que je puisse démo parseInt() plus tard dans ce post

Utilisation:

<p>
 {{#xif " this.name == 'Sam' && this.age === '12' " }}
   BOOM
 {{else}}
   BAMM
 {{/xif}}
</p>

Sortie

<p>
  BOOM
</p>

JavaScript: (il dépend d'un autre helper - continuez à lire)

 Handlebars.registerHelper("xif", function (expression, options) {
    return Handlebars.helpers["x"].apply(this, [expression, options]) ? options.fn(this) : options.inverse(this);
  });

Guidon Helper: {{x EXPRESSION}}

Une aide à exécuter javascript expressions

  1. L'EXPRESSION est correctement Chaîne d'échappement
  2. Oui vous avez BESOIN pour échapper correctement les littéraux de chaîne ou tout simplement alterner les guillemets simples et doubles
  3. pour accéder à toute fonction ou une propriété, vous devez utiliser window.functionName() au lieu de simplement en functionName(), vous remarquerez que j'ai eu à l'utiliser window.parseInt() au lieu de parseInt()
  4. cet exemple suppose que vous avez passé ce contexte, à vos guidon template( {name: 'Sam', age: '20' } ), age est string pour la démo fin, il peut être n'importe quoi..

Utilisation:

<p>Url: {{x "'hi' + this.name + ', ' + window.location.href + ' <---- this is your href,' + ' your Age is:' + window.parseInt(this.age, 10)"}}</p>

Sortie:

<p>Url: hi Sam, http://example.com <---- this is your href, your Age is: 20</p>

JavaScript:

Cela ressemble un peu gros parce que je syntaxe étendue et commenté sur presque chaque ligne à des fins de clarté

Handlebars.registerHelper("x", function (expression, options) {
  var fn = function(){}, result;

  // in a try block in case the expression have invalid javascript
  try {
    // create a new function using Function.apply, notice the capital F in Function
    fn = Function.apply(
      this,
      [
        'window', // or add more '_this, window, a, b' you can add more params if you have references for them when you call fn(window, a, b, c);
        'return ' + expression + ';' // edit that if you know what you're doing
      ]
    );
  } catch (e) {
    console.warn('[warning] {{x ' + expression + '}} is invalid javascript', e);
  }

  // then let's execute this new function, and pass it window, like we promised
  // so you can actually use window in your expression
  // i.e expression ==> 'window.config.userLimit + 10 - 5 + 2 - user.count' //
  // or whatever
  try {
    // if you have created the function with more params
    // that would like fn(window, a, b, c)
    result = fn.bind(this)(window);
  } catch (e) {
    console.warn('[warning] {{x ' + expression + '}} runtime error', e);
  }
  // return the output of that result, or undefined if some error occured
  return result;
});

Moar

si vous souhaitez accéder à un niveau supérieur de la portée, c'est légèrement différent, l'expression est à la JOINTURE de tous les arguments, utilisation: dire les données de contexte ressemble à ceci:

// data
{name: 'Sam', age: '20', address: { city: 'yomomaz' } }

// in template
// notice how the expression wrap all the string with quotes, and even the variables
// as they will become strings by the time they hit the helper
// play with it, you will immediately see the errored expressions and figure it out

{{#with address}}
    {{z '"hi " + "' ../this.name '" + " you live with " + "' city '"' }}
{{/with}}

Javascript:

Handlebars.registerHelper("z", function () {
    var options = arguments[arguments.length - 1]
    delete arguments[arguments.length - 1];
    return Handlebars.helpers["x"].apply(this, [Array.prototype.slice.call(arguments, 0).join(''), options]);
});

Handlebars.registerHelper("zif", function () {
    var options = arguments[arguments.length - 1]
    delete arguments[arguments.length - 1];
    return Handlebars.helpers["x"].apply(this, [Array.prototype.slice.call(arguments, 0).join(''), options]) ? options.fn(this) : options.inverse(this);
});

19voto

devongovett Points 1557

Un problème avec toutes les réponses postées ici, c'est qu'ils ne fonctionnent pas avec les propriétés liées, c'est à dire si la condition n'est pas réévalué lorsque les propriétés concernées changement. Ici est un peu une version plus avancée de l'aide de soutien liaisons. Il utilise le lier fonction de la Braise à la source, ce qui est également utilisé pour mettre en œuvre la normale de Braise #if helper.

Celui-ci est limité à une seule tenue de propriété sur la gauche, en la comparant à une constante sur le côté droit, ce qui je pense est assez bon pour la plupart des fins pratiques. Si vous avez besoin de quelque chose de plus avancé que d'une simple comparaison, alors peut-être il serait bon de commencer à déclarer des propriétés calculées et l'aide de la normale #if helper à la place.

Ember.Handlebars.registerHelper('ifeq', function(a, b, options) {
  return Ember.Handlebars.bind.call(options.contexts[0], a, options, true, function(result) {
    return result === b;
  });
});

Vous pouvez l'utiliser comme ceci:

{{#ifeq obj.some.property "something"}}
  They are equal!
{{/ifeq}}

12voto

Vincent Points 325

Meilleure solution qui fonctionnent essentiellement avec n’importe quel opérateur binaire (au moins les numéros, les chaînes ne fonctionnent bien avec eval, prenez soin de POSSIBLE INJECTION de SCRIPT si USING A NON défini les entrées d’utilisateur avec opérateur) :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X