车把有两套不同的属性。帮手还是部分?

时间:2016-04-08 13:30:06

标签: javascript handlebars.js

我有一个json对象,让我们用团队称它为teamData。

我希望能够将一个变量(例如Primary或​​Secondary)传递给一个调用,并让它使用所选TeamType的状态呈现状态下拉列表。

我一直在阅读许多把手教程,但它们都没有真正处理对象的多个属性,或者显示如何将值从一个属性链接到另一个属性。

状态下拉很简单

 <script type="text/x-handlebars-template" id="tmpl-states">
      <select>
           {{#eachProperty States}}
                <option name="{{property}}">{{value}}</option>
           {{/eachProperty}}
      </select>
 </script>

 Handlebars.registerHelper('eachProperty', function (context, options) {
     var ret = "";
     for (var prop in context) {
          ret = ret + options.fn({ property: prop, value: context[prop] });
     }
     return ret;
 });

但我想做的更像是(在sudo中)

 renderTemplate("tmps-all", "container", "data", "variable");

 <script type="text/x-handlebars-template" id="tmps-all">
      {{#each Teams}}
           {{#if TeamType == variable}} // e.g. Primary
                var State = this.State;
           {{/if}}
      {{/each}}
      <select>
           {{#eachProperty States}}
                {{#if property == State}} // e.g NY
                <option name="{{property}}" selected>{{value}}</option>
                {{/else}}
                <option name="{{property}}">{{value}}</option>
                {{/if}}
           {{/eachProperty}}
      </select>
 </script>

var teamData = {"Teams":[{"TeamType":"Primary","State":"NY"},{"TeamType":"Secondary","State":"CA"}],"States":{"AK":"Alaska","AL":"Alabama","AR":"Arkansas","AZ":"Arizona","CA":"California","CO":"Colorado","CT":"Connecticut","DC":"District of Columbia","DE":"Delaware","FL":"Florida","GA":"Georgia","HI":"Hawaii","IA":"Iowa","ID":"Idaho","IL":"Illinois","IN":"Indiana","KS":"Kansas","KY":"Kentucky","LA":"Louisiana","MA":"Massachusetts","MD":"Maryland","ME":"Maine","MI":"Michigan","MN":"Minnesota","MO":"Missouri","MS":"Mississippi","MT":"Montana","NC":"North Carolina","ND":"North Dakota","NE":"Nebraska","NH":"New Hampshire","NJ":"New Jersey","NM":"New Mexico","NV":"Nevada","NY":"New York","OH":"Ohio","OK":"Oklahoma","OR":"Oregon","PA":"Pennsylvania","PR":"Puerto Rico","RI":"Rhode Island","SC":"South Carolina","SD":"South Dakota","TN":"Tennessee","TX":"Texas","UT":"Utah","VA":"Virginia","VT":"Vermont","WA":"Washington","WI":"Wisconsin","WV":"West Virginia","WY":"Wyoming"}};

1 个答案:

答案 0 :(得分:1)

您无需eachProperty助手。它给你的功能已存在于Handlebars中。让我们删除该帮助器并将我们的模板更新为以下内容(注意:我将name属性替换为value):

<select>
    {{#each States}}
        <option value="{{@key}}">{{this}}</option>
    {{/each}}
</select>

现在开始设置selected归属的任务。

您在模板中尝试了太多逻辑。模板不能初始化变量。在呈现模板之前,应该完成这项工作。我们希望我们的代码调用模板方法为模板提供所需的所有数据。这意味着向我们的模板传递如下数据结构:

[
    {
        value: 'AK',
        label: 'Alaska',
        selected: false
    },
    {
        value: 'AL',
        label: 'Alabama',
        selected: false
    },
    // and so on...
]

我们的代码将完成构建此数据结构的工作:

var selected_team = teamData.Teams.find(team => team.TeamType === 'Primary');
var states = Object.keys(teamData.States).map(key => ({
    value: key,
    label: teamData.States[key],
    selected: (key === selected_team.State)
}));

现在我们可以修改我们的模板来处理我们的新数据结构:

<select>
    {{#each this}}
        <option value="{{value}}" {{#if selected}}selected{{/if}}>{{label}}</option>
    {{/each}}
</select>

当我们调用模板时,我们只需传入states变量:

renderTemplate(states);

然而: 由于我们背后的所有工作,我想补充一点,我认为重新渲染此模板没有任何目的只是为了反映更改的选定选项。使用DOM进行更改对我来说更有意义。如下所示就足够了:

document.querySelector('#Select [value="NY"]').selected = true;

请参阅:https://stackoverflow.com/a/7373115/3397771