Handlebars.js: Ayudante de {{#switch}}

Creado en 22 dic. 2014  ·  15Comentarios  ·  Fuente: handlebars-lang/handlebars.js

Esto es muy útil y creo que sería mejor si fuera nativo de la biblioteca:

{{#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}}

Comentario más útil

Esta página es actualmente el tercer resultado de búsqueda de Google para "Ayudante de cambio de manillares". Para el beneficio de las personas que llegan aquí desde un motor de búsqueda, aquí hay una implementación de Chris Montrois que admite case como {{#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);
    }
});

Aquí hay un asistente case mejorado que admite cláusulas con un número variable de valores, como {{#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);
    }
});

Todos 15 comentarios

Esto es algo que se puede lograr (de una manera hacky) usando ayudantes estándar. Deseamos que los ayudantes integrados sean relativamente livianos, en lugar de permitir que terceros implementen los ayudantes que necesitan, de la manera que más les convenga, utilizando la API de ayuda.

Esta página es actualmente el tercer resultado de búsqueda de Google para "Ayudante de cambio de manillares". Para el beneficio de las personas que llegan aquí desde un motor de búsqueda, aquí hay una implementación de Chris Montrois que admite case como {{#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);
    }
});

Aquí hay un asistente case mejorado que admite cláusulas con un número variable de valores, como {{#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);
    }
});

Muy lindo, corto y dulce. Me encontré con otros mucho más largos en el pasado.

Un par de cosas para agregar podrían ser {{#default}} {{/default}} y {{#case "value" break=true}} .

@stevenvachon Según lo solicitado;)

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- ¿Dónde deberíamos incluir esto?

@jimkoul Estas son funciones auxiliares, por lo que depende de su configuración.

Mi configuración (con Gulp + gulp-hb) admite la especificación de un patrón global para archivos js que exportan funciones auxiliares, como se muestra arriba, por lo que se ve así:

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

Si aún no está seguro, investigue un poco sobre cómo funcionan las funciones auxiliares con los manillares y cómo implementarlas con cualquier implementación de manillares que esté utilizando.

Sería bueno si pudiéramos pasar la variable a través del nombre del conmutador y no tener que escribir un {{assign}} completo a través de cada uno. De esa forma, la opción se convierte en el valor de la variable.

Además, también recibo un mensaje indefinido a pesar de que la variable está cambiando correctamente cuando se cumple el caso.

Esto es lo que tengo para el ayudante

"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);
    }
});

Esto es lo que tengo en mi archivo 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}}

o por alguna razón, lo anterior hace que el valor predeterminado siempre tenga prioridad, incluso cuando se cumple uno de los casos anteriores.

Esto es lo que uso:

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);
    }
});

Los interruptores tienen nombre, por lo que es posible bifurcarlos (¿imbricación? No estoy seguro de la palabra ...)
Además, el descanso siempre se realiza cuando se cumple una condición.

es decir:

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

Estoy seguro de que no entiendo cómo funciona esto, así que me disculpo por mi confusión, pero ... ¿Es posible que el cambio funcione dentro de un each ? Lo he estado probando, pero sigo recibiendo errores.

Esto es lo que tengo:

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

Pero estoy entendiendo esto:

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

Me parece que this debe ser algo diferente de lo esperado, pero realmente no lo sé.

Parece que pude hacerlo funcionar cambiando switch siguiente manera:

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

Pero supongo que estoy perdiendo algo por otros casos. Dicho esto, siempre podría adjuntar estos valores a options , y creo que funcionaría.

@ Billy- @ a-le?

@infinityplusone, desafortunadamente, no he usado los manubrios correctamente en años, así que imagino que la implementación del ayudante puede haber cambiado mucho desde que escribí eso, que es probablemente la razón por la que no funcionó como se esperaba. Sin embargo, no estoy seguro, lamento decepcionar.

@infinityplusone Si usa mi versión, debe "nombrar" el interruptor.
Entonces, con tu ejemplo:

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

para bloque de interruptores anidado

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 );

¿Qué tal esto?
solo si desea convertir la clave en valor.

javascript
module.exports = function (input, cases, values) {
const caseArray = cases.split (',')
const valueArray = valores.split (',')
índice constante = caseArray.indexOf (entrada)

return valueArray [índice]
};
manillares
{{cambiar "Y" "Y, N, D", "SÍ, NO, ELIMINADO"}}
`` ``

¿Fue útil esta página
0 / 5 - 0 calificaciones