Handlebars.js: {{#switch}}ヘルパー

作成日 2014年12月22日  ·  15コメント  ·  ソース: handlebars-lang/handlebars.js

これは非常に便利であり、ライブラリにネイティブであることが最善だと思います。

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

最も参考になるコメント

このページは現在、「ハンドルバースイッチヘルパー」の3番目のGoogle検索結果です。 検索エンジンからここに到着する人々のために、 {{#case "page1"}}などの単一値のcase句をサポートするChrisMontroisによる実装を次に示します。

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

これは、 {{#case "page1" "page2"}}などの可変数の値を持つ句をサポートする改良されたcaseヘルパーです。

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

全てのコメント15件

これは、標準のヘルパーを使用して(ハッキーな方法で)達成できるものです。 組み込みのヘルパーを比較的軽量に保ち、代わりに、サードパーティがヘルパーAPIを使用して、必要なヘルパーを最適な方法で実装できるようにしたいと考えています。

このページは現在、「ハンドルバースイッチヘルパー」の3番目のGoogle検索結果です。 検索エンジンからここに到着する人々のために、 {{#case "page1"}}などの単一値のcase句をサポートするChrisMontroisによる実装を次に示します。

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

これは、 {{#case "page1" "page2"}}などの可変数の値を持つ句をサポートする改良されたcaseヘルパーです。

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

とても素敵で、短くて甘い。 私は過去にはるかに長いものに出くわしました。

追加するものは{{#default}} {{/default}}{{#case "value" break=true}}です。

@stevenvachonリクエストに応じて;)

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-これをどこに含めるべきですか?

@jimkoulこれらはヘルパー関数であるため、セットアップによって異なります。

私のセットアップ(Gulp + gulp-hbを使用)は、上記のようにヘルパー関数をエクスポートするjsファイルのglobパターンの指定をサポートしているため、次のようになります。

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

それでもわからない場合は、ヘルパー関数がハンドルバーでどのように機能するか、および使用しているハンドルバーの実装でそれらを実装する方法について少し調べてください。

スイッチ名を介して変数を渡すことができ、それぞれに完全な{{assign}}を書き込む必要がない場合は便利です。 そうすれば、オプションは変数値になります。

さらに、ケースが満たされたときに変数が正しく変更されているにもかかわらず、未定義のメッセージが表示されます。

これは私がヘルパーのために持っているものです

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

これは私が私の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}}

または、上記のいずれかのケースが満たされた場合でも、上記の理由により、デフォルトが常に優先されます。

これが私が使用するものです:

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

スイッチには名前が付けられているので、それらを分岐させることができます(覆瓦?単語についてはよくわかりません...)
また、条件が満たされたときに常にブレークが行われます

NS:

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

これがどのように機能するかを理解していないと確信しているので、混乱して申し訳ありませんが...スイッチがeach内で機能することは可能ですか? 試してみましたが、エラーが発生し続けます。

これが私が持っているものです:

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

しかし、私はこれを取得しています:

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

thisは予想とは違うものに違いないと思いますが、よくわかりません。

switchを次のように変更することで、機能させることができたようです。

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

しかし、私は他の場合のために何かを失っていると推測しています。 そうは言っても、私はいつでもこれらの値をoptionsに付加することができ、それでうまくいくと思います。

@ Billy- @ a-le?

@infinityplusone残念ながら、私はハンドルバーを何年も適切に使用していなかったので、それを書いた後、ヘルパーの実装が大幅に変更された可能性があると思います。これがおそらく期待どおりに機能しなかった理由です。 よくわかりませんが、がっかりさせて申し訳ありません。

@infinityplusone私のバージョンを使用する場合は、スイッチに「名前を付ける」必要があります。
だから、あなたの例で:

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

ネストされたスイッチブロックの場合

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

これはどう?
キーを値に変換したい場合にのみ。

`` `` javascript
module.exports = function(input、cases、values){
const caseArray = Cases.split( '、')
const valueArray = values.split( '、')
const index = caseArray.indexOf(input)

戻り値Array [インデックス]
};
ハンドルバー
{{switch "Y" "Y、N、D"、 "YES、NO、DELETED"}}
「」

このページは役に立ちましたか?
0 / 5 - 0 評価