Как подключить таблицу CSS-сетки к массиву?
У меня на.HBS настроена сетка 5x5. Я хочу каким-то образом удерживать состояние моей игры с помощью ember.js OCTANE. Как мне это сделать и как лучше всего? Поделитесь, пожалуйста, идеями. Мне нужно создать модель? Я новичок в Octane, пожалуйста, помогите. Пока я только что создал компонент сетки и пытаюсь использовать отслеживание мерцания с помощью массива.
ОБД:
<table class="quantize" style="width: 80%">
{{#each (range 0 5) as |row|}}
<tr class="">
{{#each (range 0 5) as |cell|}}
<td
class="border border-dark"
style="width:10%">
{{cell}}
</td>
{{/each}}
</tr>
{{/each}}
</table>
1 ответ
Я думаю, что сохранение состояния компонента является самым простым в тех случаях, когда ваши исходные данные жестко запрограммированы и вам не нужно получать их с сервера или сохранять на сервере.
Я рекомендую ознакомиться с Руководством по Octane, чтобы изучить эти закономерности более подробно. Вы можете получить к нему доступ здесь.
Сохранение состояния массива в компоненте Octane:
Сначала мы помещаем данные массива в отслеживаемое свойство и пишем действие, которое может изменять эти данные:
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class MyComponent extends Component {
@tracked items = [
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
];
@action
editItem(item) {
this.items[0][0] = item // make some changes
// The line below is important when working with tracked arrays and objects. Always "reset" the array whenever you make changes. This tells Ember to update what is rendered.
this.items = this.items;
}
}
Мы перебираем этот 2D-массив, используя each
помощники. Мы называем эти элементыthis.items
поскольку они определены в "этом компоненте"
<table class="quantize" style="width: 80%">
{{#each this.items as |row|}}
<tr class="">
{{#each row as |cell|}}
<td
class="border border-dark"
style="width:10%">
{{cell}}
</td>
{{/each}}
</tr>
{{/each}}
</table>
Сохранение состояния в модели маршрута
Если вы хотите поместить данные массива в ловушку модели маршрута, вы тоже можете это сделать. Однако модель в основном используется, когда вы получаете данные из API. Плюсы в том, что Ember обрабатывает асинхронную загрузку и рендеринг за вас, минусы в том, что это сложнее. Компоненту Octane разрешено вносить изменения только в те данные, которыми он "владеет". Если необходимо внести изменения в данные, которые были переданы из родительского компонента или маршрута, это должно быть сделано путем вызова функции, которая также была передана. Это называется "односторонней привязкой".
Сначала мы возвращаем данные из хука модели маршрута:
// routes/my-route.js
import Route from '@ember/routing/route';
export default class MyRoute extends Route {
model() {
return [
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
];
// or return a fetch() request for that data
}
}
// controllers/my-route.js
import Controller from '@ember/controller';
import { action } from '@ember/object';
export default class MyRouteController extends Controller {
@action
editItems(items) {
this.model = items;
}
}
Мы передаем эти данные модели и наше действие editItems компоненту, который отображает таблицу:
<!-- templates/my-route.hbs -->
<MyComponent @items={{this.model}} @editItems={{action "editItems"}} />
В нашем компоненте мы называем элементы @items
и нет this.items
. @
используется, когда данные поступают извне, например, от родительского маршрута или компонента.
<!-- my-component.hbs -->
<table class="quantize" style="width: 80%">
{{#each @items as |row|}}
<tr class="">
{{#each row as |cell|}}
<td
class="border border-dark"
style="width:10%">
{{cell}}
</td>
{{/each}}
</tr>
{{/each}}
</table>
Затем, когда вы хотите внести изменения в массив, вы должны вызвать editItems
переданная функция. Она доступна как this.args.editItems
. this.args
все, что было передано в компонент от родителя.
import Component from '@glimmer/component';
import { action } from '@ember/object';
export default class MyComponent extends Component {
@action
buttonWasClicked(item) {
this.args.editItems(item)
}
}
Или вы можете использовать действие, переданное непосредственно в вашем шаблоне, и передать ему элемент, который вы хотите изменить.
<!-- my-component.hbs -->
<button {{on "click" (fn @editItems item)}}>edit item</button>