如何在Handlebars模板中设置选定的选择选项

jan*_*alk 50 javascript

使用像这样的Handlebars.js模板......

<select>
    <option value="Completed">Completed</option>
    <option value="OverDue">OverDue</option>
    <option value="SentToPayer">SentToPayer</option>
    <option value="None">None</option>
</select>
Run Code Online (Sandbox Code Playgroud)

......和这样的数据......

{
    "id"     : 1,
    "name"   : "World"
    "status" : "OverDue",
    "date"   : "2012-12-21"
}
Run Code Online (Sandbox Code Playgroud)

我想像这样呈现HTML.

<select>
    <option value="Completed">Completed</option>
    <option value="OverDue" selected="selected">OverDue</option>
    <option value="SentToPayer">SentToPayer</option>
    <option value="None">None</option>
</select>
Run Code Online (Sandbox Code Playgroud)

哪种方式最简单?

jan*_*alk 86

我找到了很多过于复杂的解决方案,并决定使用Handlebars帮助器编写自己的解决方案.

有了这部分(使用Jquery)......

    window.Handlebars.registerHelper('select', function( value, options ){
        var $el = $('<select />').html( options.fn(this) );
        $el.find('[value="' + value + '"]').attr({'selected':'selected'});
        return $el.html();
    });
Run Code Online (Sandbox Code Playgroud)

您可以使用{{#select status}}在Handlebars模板中包装选择...

<select>
    {{#select status}}
    <option value="Completed">Completed</option>
    <option value="OverDue">OverDue</option>
    <option value="SentToPayer">SentToPayer</option>
    <option value="None">None</option>
    {{/select}}
</select>
Run Code Online (Sandbox Code Playgroud)

并最终得到这个......

<select>
    <option value="Completed">Completed</option>
    <option value="OverDue" selected="selected">OverDue</option>
    <option value="SentToPayer">SentToPayer</option>
    <option value="None">None</option>
</select>
Run Code Online (Sandbox Code Playgroud)

普雷斯托!

  • 不幸的是依赖于jQuery/DOM解析.因此,当Handlebars用于服务器端绑定(Node.js)时,这不起作用. (4认同)
  • 我写了一个版本,它只是映射在行上并替换匹配的选定值.我相信很多人都会写自己的,但这是一条腿 - https://gist.github.com/TheFuzzball/6173ab951d8b1dc4602e (2认同)

Dan*_*Dan 31

我只是有一个与OP类似的需求 - 有一组静态选择选项,但是是一个动态选择值.我真的很喜欢@ janjarfalk的解决方案,但是我使用的是node.js并没有拉入jQuery.所以,我根据RegExp将我自己的变体放在一起.希望这对其他人有帮助.

把手帮手:

hbs.registerHelper('select', function(selected, options) {
    return options.fn(this).replace(
        new RegExp(' value=\"' + selected + '\"'),
        '$& selected="selected"');
});
Run Code Online (Sandbox Code Playgroud)

把手模板:

<select>
    {{#select CurrentSort}}
    <option value="1">Most Recent First</option>
    <option value="2">Most Recent Last</option>
    <option value="3">Highest Score First</option>
    <option value="4">Highest Score Last</option>
    <option value="5">Most Comments</option>
    <option value="6">Fewest Comments</option>
    <option value="7">Most Helpful Votes</option>
    <option value="8">Fewest Helpful Votes</option>
    {{/select}}
</select>
Run Code Online (Sandbox Code Playgroud)

即使您不使用该value属性,也可以调整帮助程序- 只需调整正则表达式以搜索元素文本,并在匹配的文本之前执行字符串替换.

  • +1表示不需要使用DOM的解决方案. (6认同)

laz*_*azd 17

我看到了@janjarfalk发布的非常聪明的解决方案,并意识到它对于没有值属性(例如<option>Value</option>)定义的选项不起作用.我的应用程序需要这个,我想要一个用vanilla JavaScript完成性能的助手,所以我想出了以下内容.

此解决方案<option>Both a label and a value</option>除了<option value="aValue">A label</option>使用jQuery 之外还支持并且速度更快.

Handlebars.registerHelper('select', function(value, options) {
    // Create a select element 
    var select = document.createElement('select');

    // Populate it with the option HTML
    select.innerHTML = options.fn(this);

    // Set the value
    select.value = value;

    // Find the selected node, if it exists, add the selected attribute to it
    if (select.children[select.selectedIndex])
        select.children[select.selectedIndex].setAttribute('selected', 'selected');

    return select.innerHTML;
});
Run Code Online (Sandbox Code Playgroud)

用法:

<select>
    {{#select status}}
    <option>Option 1</option>
    <option>Option 2</option>
    <option value="Option 3">Option 3 (extra info)</option>
    <option value="Option 4">Option 4 (more extra)</option>
    {{/select}}
</select>
Run Code Online (Sandbox Code Playgroud)


小智 11

适合我

<select>
    <option value="{{status}}" hidden="hidden" selected="selected">{{status}}</option>
    <option value="Completed">Completed</option>
    <option value="OverDue">OverDue</option>
    <option value="SentToPayer">SentToPayer</option>
    <option value="None">None</option>
</select>
Run Code Online (Sandbox Code Playgroud)


小智 9

由于上下文的原因,当使用"每个"帮助器构建动态的东西时,我遇到了"选择块"方法的问题.

这是我的解决方案:

  Handlebars.registerHelper('option', function(value, label, selectedValue) {
    var selectedProperty = value == selectedValue ? 'selected="selected"' : '';
    return new Handlebars.SafeString('<option value="' + value + '"' +  selectedProperty + '>' + label + "</option>");
  });
Run Code Online (Sandbox Code Playgroud)

和模板:

<select>
  {{#each status}}
    {{option id name ../statusId}}
  {{/each}}
</select>
Run Code Online (Sandbox Code Playgroud)


Ism*_*ilS 6

改进@lazd的答案,在没有匹配时选择第一个选项.

Handlebars.registerHelper('select', function(value, options) {
    // Create a select element 
    var select = document.createElement('select');


// Populate it with the option HTML
$(select).html(options.fn(this));

//below statement doesn't work in IE9 so used the above one
//select.innerHTML = options.fn(this); 

    // Set the value
    select.value = value;

    // Find the selected node, if it exists, add the selected attribute to it
    if (select.children[select.selectedIndex]) {
        select.children[select.selectedIndex].setAttribute('selected', 'selected');
    } else { //select first option if that exists
        if (select.children[0]) {
            select.children[0].setAttribute('selected', 'selected');
        }
    }
    return select.innerHTML;
});
Run Code Online (Sandbox Code Playgroud)

用法保持不变:

<select>
    {{#select status}}
    <option>Option 1</option>
    <option>Option 2</option>
    <option value="Option 3">Option 3 (extra info)</option>
    <option value="Option 4">Option 4 (more extra)</option>
    {{/select}}
</select>
Run Code Online (Sandbox Code Playgroud)