Почему не отслеживается обновление моего массива в Ember Octane?
Я пробую Octane, и по какой-то причине, если я показываю массив в шаблоне и добавляю в него новый объект, пользовательский интерфейс не обновляется. Что я делаю неправильно?
Вот мой шаблон:
<label for="new-field-name">Field Name</label>
<Input id="new-field-name" @value={{this.newFieldName}} type="text" />
<button {{on "click" this.addField}}>Add field</button>
{{#each this.fields as |field|}}
<p>{{field.name}}</p>
{{/each}}
И компонент:
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class ConfigControlsComponent extends Component {
@tracked fields = []
@tracked newFieldName = ''
@action addField() {
this.fields.push({
name: this.newFieldName
})
console.log(this.fields)
}
}
console.log
показывает массив с новым объектом, добавленным к нему, и fields
массив отслеживается, но ничего не меняется, когда я нажимаю кнопку.
2 ответа
Когда вы используете tracked
с массивами вам нужно "сбросить" массив, чтобы Ember заметил, что произошли изменения. Попробуй сделать this.fields = this.fields
после добавления нового объекта в массив.
export default class ConfigControlsComponent extends Component {
@tracked fields = []
@tracked newFieldName = ''
@action addField() {
this.fields.push({
name: this.newFieldName
})
this.fields = this.fields // add this line
}
}
Если вы пытаетесь использовать tracked
с объектом вместо массива у вас есть два варианта:
Во-первых, вы можете создать класс, в котором отслеживаются все свойства объекта:
import { tracked } from '@glimmer/tracking';
class Address {
@tracked street;
@tracked city;
}
class Person {
address = new Address();
get fullAddress() {
let { street, city } = this.address;
return `${street}, ${city}`;
}
}
Или, во-вторых, вы можете использовать тот же подход "сброса", что и в примере с массивом выше.
Массивы не отслеживаются автоматически при изменении одного из их элементов. Вы не можете:
this.fields.push({
name: this.newFieldName
})
Но они отслеживаются, если вы измените весь массив, например, с помощью оператора распространения:
this.fields = [...this.fields, {name: this.newFieldName}]
Или, в конце концов, вы можете использовать EmberArray , см. Https://guides.emberjs.com/release/in-depth-topics/autotracking-in-depth/#toc_arrays