как мне использовать и устанавливать пользовательские переменные из Handlebars.js блокировать?

#javascript #jquery #handlebars.js

#javascript #jquery #handlebars.js

Вопрос:

Итак, допустим, у меня есть этот json

 food = [
  {
    name: "banana",
    type: "fruit",
    color: "yellow"
  },
  {
    name: "apple",
    type: "fruit",
    color: red"
  },
  {
    name: "strawberry",
    type: "fruit",
    color: "red"
  },
  {
    name: "carrot",
    type: "vegetable",
    color: "orange"
  },
  {
    name: "chocolate",
    type: "dessert",
    color: "brown"
  }
]
  

И я хочу отобразить его в таблице, подобной этой:

 <table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
    </tr>
  </thead>
  <tbody>
  {{#each food}
    {{#if lastType == "" or lastType != type}}
    <tr>
      <td colspan="2">{{type}}
    </tr>
    {{/if}}
    <tr>
      <td>{{name}}</td>
      <td>{{Color}}</td>
    </tr>
  {{/each}}
  </tbody>
</table>
  

Но я хочу добавлять еще одну строку таблицы каждый раз, когда появляется новое значение для свойства type . Итак, в основном таблица finally будет выглядеть следующим образом:

 <table>
    <thead>
    <tr>
        <th>Name</th>
        <th>Color</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td colspan="2">fruit</td>
    </tr>
    <tr>
        <td>banana</td>
        <td>yellow</td>
    </tr>
    <tr>
        <td>apple</td>
        <td>red</td>
    </tr>
    <tr>
        <td>strawberry</td>
        <td>red</td>
    </tr>
    <tr>
        <td colspan="2">vegetable</td>
    </tr>
    <tr>
        <td>banana</td>
        <td>yellow</td>
    </tr>
    <tr>
        <td colspan="2">dessert</td>
    </tr>
    <tr>
        <td>chocolate</td>
        <td>brown</td>
    </tr>
    </tbody>
</table>
  

Как я мог бы добиться чего-то подобного?

Ответ №1:

Ваша цель — отобразить ваши продукты в группах с типом в качестве заголовка группы. Я бы не советовал указывать логику для выполнения этой группировки в шаблоне, поскольку это будет сложно достичь. Лучшим решением, которое сохранит шаблон чистым и понятным, было бы выполнить группировку данных перед отправкой их в шаблон.

В идеальной структуре данных продукты должны быть проиндексированы по их типу. Мы могли бы достичь этого с помощью объекта, подобного следующему:

 {
    "fruit": [
        {
            "color": "yellow",
            "name": "banana",
            "type": "fruit"
        },
        {
            "color": "red",
            "name": "apple",
            "type": "fruit"
        }
    ],
    "vegetable": [
        {
            "color": "orange",
            "name": "carrot",
            "type": "vegetable"
        }
    ],
    "dessert": [
        {
            "color": "brown"
            "name": "chocolate",
            "type": "dessert"
        }
    ]
}
  

С такой структурой данных было бы просто получить группировки в нашем шаблоне, используя вложенные {{#each}} блоки. (Я предполагаю, что мы назвали наш объект «foodsByType»)

 {{#each foodsByType}}
    <tr>
        <td colspan="2">{{@key}}</td>
    </tr>
    {{#each this}}
        <tr>
            <td>{{name}}</td>
            <td>{{color}}</td>
        </tr>
    {{/each}}
{{/each}}
  

Если вы ищете хороший способ построения foodsByType объекта, вы можете рассмотреть возможность использования Array.prototype.reduce:

 const foodsByType = food.reduce((acc, foodItem) => {
    if (!acc[foodItem.type]) {
        acc[foodItem.type] = [];
    }
  
    acc[foodItem.type].push(foodItem);
  
    return acc;
}, {});
  

Я создал скрипку для вашей справки.

Комментарии:

1. Да, это было намного проще, чем то, как я пытался это сделать. Сработало как шарм. Спасибо!