标准化 Dropdown 的 Selected Handlebars Helper

Standardize Dropdown's Selected Handlebars Helper

我面临以下使用 Handlebars 构建下拉菜单的挑战。

不要以这种方式对下拉菜单的 select 进行建模:

<div class="form-floating col-3">
            <select name="sport" class="form-select" id="floatingSelect">
                <option {{selectedSport sport 'all'}} value="all">All</option>
                <option {{selectedSport sport 'Hiking'}} value="Hiking">Hiking</option>
                <option {{selectedSport sport 'Mountaineering'}} value="Mountaineering">Mountaineering</option>
                <option {{selectedSport sport 'Climbing'}} value="Climbing">Climbing</option>
                <option {{selectedSport sport 'Mountain biking'}} value="Mountain biking">Mountain biking</option>
            </select>
            <label for="floatingSelect">Sport</label>
        </div>
        <div class="form-floating col-2">
            <select name="difficulty" class="form-select" id="floatingSelect">
                <option {{selectedDifficulty difficulty 'all'}} value="all">All</option>
                <option {{selectedDifficulty difficulty 'Easy'}} value="Easy">Easy</option>
                <option {{selectedDifficulty difficulty 'Medium'}} value="Medium">Medium</option>
                <option {{selectedDifficulty difficulty 'Hard'}} value="Hard">Hard</option>
                <option {{selectedDifficulty difficulty 'Expert'}} value="Expert">Expert</option>
            </select>
            <label for="floatingSelect">Difficulty</label>
        </div>

我想为他们两个使用同一个助手,但我仍然不知道该怎么做。 (顺便说一句,忽略我应该使用 {{#each}} 来显示选项的事实:P)

控制器:

module.exports.list = (req, res, next) => {
const filters = req.query;
const { location, sport, difficulty } = req.query;
const criterial = Object.keys(filters)
    .filter((key => filters[key] !== 'all'))
    .reduce((criterial, filter) => {
        if (filters[filter]) criterial[filter] = filters[filter];
        return criterial;
    }, {});

    Route.find(criterial)
    .then(routes => {
        res.render('routes/list', { routes, location, sport, difficulty })
    })
    .catch(next)
   }

帮手:

hbs.registerHelper('selectedSport', (option, sportValue) => {
    return option === sportValue ? ' selected' : '';
})

hbs.registerHelper('selectedDifficulty', (option, difficultyValue) => {
    return option === difficultyValue ? ' selected' : '';
})

非常感谢您的帮助! :)

最后我是这样解决的:

我没有直接在 HBS 上键入所有选项,而是使用呈现每个选项的助手创建这些选项。

        <div class="form-floating col-3">
            <select name="sport" class="form-select" id="floatingSelect">
                {{#each sportOptions as |sportOption|}}
                {{option ../sport sportOption}}
                {{/each}}
            </select>
            <label for="floatingSelect">Sport</label>
        </div>
        <div class="form-floating col-2">
            <select name="difficulty" class="form-select" id="floatingSelect">
                {{#each difficultyOptions as |difficultyOption|}}
                {{option ../difficulty difficultyOption}}
                {{/each}}
            </select>
            <label for="floatingSelect">Difficulty</label>
        </div>

助手接收 2 个参数:sport 和 sportOption,根据它们的值,returns一个包含选项与所选属性的字符串。

hbs.registerHelper('option', function (selectedValue, value) {
    const selectedProperty = value == selectedValue ? 'selected' : '';
    return new hbs.SafeString(`<option value=${value} ${selectedProperty}>${value}</option>`);
  });

sportOption 和 difficultyOption 是包含所有可能性的数组。

我希望,如果其他人遇到同样的问题,这会有所帮助:)