Handlebars.js: {{#switch}} assistant

Créé le 22 déc. 2014  ·  15Commentaires  ·  Source: handlebars-lang/handlebars.js

C'est très utile et je pense que ce serait mieux s'il était natif de la bibliothèque :

{{#switch state}}
    {{#case "page1" "page2"}}toolbar{{/case}}
    {{#case "page1" break=true}}page1{{/case}}
    {{#case "page2" break=true}}page2{{/case}}
    {{#case "page3" break=true}}page3{{/case}}
    {{#default}}page0{{/default}}
{{/switch}}

Commentaire le plus utile

Cette page est actuellement le 3ème résultat de recherche Google pour "Handlebars switch helper". Pour les personnes arrivant ici depuis un moteur de recherche, voici une implémentation de Chris Montrois qui supporte les clauses case valeur unique comme {{#case "page1"}} :

Handlebars.registerHelper("switch", function(value, options) {
    this._switch_value_ = value;
    var html = options.fn(this); // Process the body of the switch block
    delete this._switch_value_;
    return html;
});

Handlebars.registerHelper("case", function(value, options) {
    if (value == this._switch_value_) {
        return options.fn(this);
    }
});

Voici un assistant case amélioré qui prend en charge les clauses avec un nombre variable de valeurs, telles que {{#case "page1" "page2"}} :

Handlebars.registerHelper("case", function() {
    // Convert "arguments" to a real array - stackoverflow.com/a/4775938
    var args = Array.prototype.slice.call(arguments);

    var options    = args.pop();
    var caseValues = args;

    if (caseValues.indexOf(this._switch_value_) === -1) {
        return '';
    } else {
        return options.fn(this);
    }
});

Tous les 15 commentaires

C'est quelque chose qui peut être réalisé (de manière bidon) en utilisant des assistants standard. Nous souhaitons garder les assistants intégrés relativement légers, au lieu de permettre à des tiers d'implémenter les assistants dont ils ont besoin, de la manière qui leur convient le mieux, en utilisant l'API d'aide.

Cette page est actuellement le 3ème résultat de recherche Google pour "Handlebars switch helper". Pour les personnes arrivant ici depuis un moteur de recherche, voici une implémentation de Chris Montrois qui supporte les clauses case valeur unique comme {{#case "page1"}} :

Handlebars.registerHelper("switch", function(value, options) {
    this._switch_value_ = value;
    var html = options.fn(this); // Process the body of the switch block
    delete this._switch_value_;
    return html;
});

Handlebars.registerHelper("case", function(value, options) {
    if (value == this._switch_value_) {
        return options.fn(this);
    }
});

Voici un assistant case amélioré qui prend en charge les clauses avec un nombre variable de valeurs, telles que {{#case "page1" "page2"}} :

Handlebars.registerHelper("case", function() {
    // Convert "arguments" to a real array - stackoverflow.com/a/4775938
    var args = Array.prototype.slice.call(arguments);

    var options    = args.pop();
    var caseValues = args;

    if (caseValues.indexOf(this._switch_value_) === -1) {
        return '';
    } else {
        return options.fn(this);
    }
});

Très joli, court et doux. J'en avais rencontré des beaucoup plus longs dans le passé.

Quelques éléments à ajouter peuvent être {{#default}} {{/default}} et {{#case "value" break=true}} .

@stevenvachon Comme demandé ;)

module.exports = {
    switch: function(value, options) {
        this._switch_value_ = value;
        this._switch_break_ = false;
        var html = options.fn(this);
        delete this._switch_break_;
        delete this._switch_value_;
        return html;
    },
    case: function(value, options) {
        var args = Array.prototype.slice.call(arguments);
        var options    = args.pop();
        var caseValues = args;

        if (this._switch_break_ || caseValues.indexOf(this._switch_value_) === -1) {
            return '';
        } else {
            if (options.hash.break === true) {
                this._switch_break_ = true;
            }
            return options.fn(this);
        }
    },
    default: function(options) {
        if (!this._switch_break_) {
            return options.fn(this);
        }
    }
};

@Billy- Où devrions-nous inclure cela?

@jimkoul Ce sont des fonctions d'assistance, cela dépend donc de votre configuration.

Ma configuration (avec Gulp + gulp-hb) prend en charge la spécification d'un modèle glob pour les fichiers js qui exportent des fonctions d'assistance, comme ci-dessus, cela ressemble donc à ceci :

// ...
.pipe(handlebars({
  helpers: 'handlebars/helpers/*.js'
})
// ...

Si vous n'êtes toujours pas sûr, faites une petite recherche sur le fonctionnement des fonctions d'assistance avec les guidons et sur la façon de les implémenter avec n'importe quelle implémentation de guidon que vous utilisez.

Ce serait bien si nous pouvions passer la variable à travers le nom du commutateur et ne pas avoir à écrire un {{assign}} complet

De plus, je reçois également un message indéfini même si la variable change correctement lorsque la casse est remplie.

C'est ce que j'ai pour l'aide

"use strict";
Handlebars.registerHelper("switch", function(value, options) {
    this._switch_value_ = value;
    this._switch_break_ = false;
    var html = options.fn(this);
    delete this._switch_break_;
    delete this._switch_value_;
    return html;
});

Handlebars.registerHelper("case", function(value, options) {
    var args = Array.prototype.slice.call(arguments);
    var options    = args.pop();
    var caseValues = args;

    if (this._switch_break_ || caseValues.indexOf(this._switch_value_) === -1) {
        return '';
    } else {
        if (options.hash.break === true) {
            this._switch_break_ = true;
        }
        return options.fn(this);
    }
});

Handlebars.registerHelper("default", function(options) {
    if (!this._switch_break_) {
        return options.fn(this);
    }
});

Voici ce que j'ai dans mon fichier hbs :

{{#assign "testParam"}}foo{{/assign}}
{{#switch testParam}}
    {{#case "boo"}}{{#assign "testParam"}}case1 has been met{{/assign}}{{/case}}
    {{#case "foo" break=true}}{{#assign "testParam"}}case2 has been met{{/assign}}{{/case}}
    {{#case "tried" break=true}}{{#assign "testParam"}}case3 has been met{{/assign}}{{/case}}
    {{#case "bwahahaha" break=true}}{{#assign "testParam"}}case4 has been met{{/assign}}{{/case}}
    {{#default break=true}}{{#assign "testParam"}}nothing matched{{/assign}}{{/default}}
{{/switch}}

{{#ttpartial "testSwitch.content"}}
        {{testParam}}
{{/ttpartial}}

ou pour une raison quelconque, ce qui précède fait que la valeur par défaut a toujours la priorité même lorsque l'un des cas ci-dessus est rencontré.

Voici ce que j'utilise :

Handlebars.registerHelper('switch', function(name, value, options) {
    this['_switch_value_' + name] = value;
    this['_switch_break_' + name] = false;
    var html = options.fn(this);
    delete this['_switch_break_' + name];
    delete this['_switch_value_' + name];
    return html;
});
Handlebars.registerHelper('case', function(name, value, options) {
    var args = Array.prototype.slice.call(arguments);
    var options    = args.pop();
    var caseValues = args;

    if ( this['_switch_break_' + name] || caseValues.indexOf(this['_switch_value_' + name]) === -1) {
        return '';
    } else {
        this['_switch_break_' + name] = true;
        return options.fn(this);
    }
});
Handlebars.registerHelper('default', function(name, options) {
    if ( !this['_switch_break_' + name] ) {
        return options.fn(this);
    }
});

Les switch sont nommés, il est donc possible de les brancher (imbrication ? pas sûr du mot...)
De plus, la pause est toujours effectuée lorsqu'une condition est remplie

c'est à dire:

    {{#switch "1" "aaa"}}
        {{#case "1" "aaa"}}
            {{#switch "2" "bbb"}}
                {{#case "2" "bbb"}}ok{{/case}}
            {{/switch}}
        {{/case}}
        {{#default "1"}}nok{{/default}}
    {{/switch}}

Je suis sûr que je ne comprends pas comment cela fonctionne, alors je m'excuse pour ma confusion, mais... Est-il possible que le commutateur fonctionne dans un each ? J'ai essayé, mais j'ai toujours des erreurs.

Voici ce que j'ai :

{{#each columns}}
    {{#switch this}}
        {{#case 'foo'}}
        {{/case}}
        {{#case 'bar'}}
        {{/case}}
    {{/switch}}
{{/each}}

Mais j'obtiens ceci :

Uncaught TypeError: Cannot create property '_switch_value_' on string 'name'

Il me semble que this doit être autre chose que ce qui est attendu, mais je ne sais pas vraiment.

On dirait que j'ai réussi à le faire fonctionner en modifiant le switch comme suit :

Handlebars.registerHelper({
    switch: function(value, options) {
        return options.fn({
            _switch_value_: value,
            _switch_break_: false
        });
    },
    //...
});

Mais je suppose que je perds quelque chose pour d'autres cas. Cela dit, je pourrais toujours attacher ces valeurs à options , et je pense que cela fonctionnerait.

@Billy- @a-le ?

@infinityplusone malheureusement, je n'ai pas utilisé correctement les guidons depuis des années, donc j'imagine que l'implémentation de l'aide a pu changer considérablement depuis que j'ai écrit cela, ce qui explique probablement pourquoi cela ne fonctionnait pas comme prévu. Je ne suis pas sûr cependant, désolé de décevoir.

@infinityplusone Si vous utilisez ma version, vous devez "nommer" le commutateur.
Alors avec ton exemple :

{{#each columns}}
    {{#switch "myswitch" this}}
        {{#case "myswitch" 'foo'}}
        {{/case}}
        {{#case "myswitch" 'bar'}}
        {{/case}}
    {{/switch}}
{{/each}}

pour bloc de commutation imbriqué

Handlebars.__switch_stack__ = [];

Handlebars.registerHelper( "switch", function( value, options ) {
    Handlebars.__switch_stack__.push({
        switch_match : false,
        switch_value : value
    });
    var html = options.fn( this );
    Handlebars.__switch_stack__.pop();
    return html;
} );
Handlebars.registerHelper( "case", function( value, options ) {
    var args = Array.from( arguments );
    var options = args.pop();
    var caseValues = args;
    var stack = Handlebars.__switch_stack__[Handlebars.__switch_stack__.length - 1];

    if ( stack.switch_match || caseValues.indexOf( stack.switch_value ) === -1 ) {
        return '';
    } else {
        stack.switch_match = true;
        return options.fn( this );
    }
} );
Handlebars.registerHelper( "default", function( options ) {
    var stack = Handlebars.__switch_stack__[Handlebars.__switch_stack__.length - 1];
    if ( !stack.switch_match ) {
        return options.fn( this );
    }
} );
{{#switch state}}
    {{#case "page1" "page2"}}page 1 or 2{{/case}}
    {{#case "page3"}}page3{{/case}}
    {{#case "page4"}}page4{{/case}}
    {{#case "page5"}}
            {{#switch s}}
                {{#case "3"}}s = 3{{/case}}
                {{#case "2"}}s = 2{{/case}}
                {{#case "1"}}s = 1{{/case}}
                {{#default}}unknown{{/default}}
            {{/switch}}
    {{/case}}
    {{#default}}page0{{/default}}
{{/switch}}
var data = {
    state : 'page5',
    s : '1'
};

var html = template( data );

Que dis-tu de ça?
juste si vous voulez convertir la clé en valeur.

````javascript
module.exports = function(entrée, cas, valeurs) {
const caseArray = cases.split(',')
const valueArray = values.split(',')
const index = caseArray.indexOf(entrée)

return valueArray[index]
} ;
guidon
{{switch "O" "O,N,D", "OUI,NON,SUPPRIMÉ"}}
````

Cette page vous a été utile?
0 / 5 - 0 notes