[英]Why won't my tracked array update in Ember Octane?
I'm trying out Octane, and for some reason, if I show an array in a template and I add a new object to it, the UI doesn't update.我正在试用 Octane,出于某种原因,如果我在模板中显示一个数组并向其中添加一个新对象,则 UI 不会更新。 What am I doing wrong?
我究竟做错了什么?
Here is my template:这是我的模板:
<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}}
And the component:和组件:
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)
}
}
The console.log
shows the array with the new object added to it, and the fields
array is tracked, but nothing changes when I click the button. console.log
显示了添加了新对象的数组,并跟踪了fields
数组,但是当我单击按钮时没有任何变化。
When you use tracked
with arrays, you need to "reset" the array so that Ember notices that there has been a change.当您对数组使用
tracked
时,您需要“重置”数组,以便 Ember 注意到发生了变化。 Try doing this.fields = this.fields
after pushing a new object into the array.在将新对象推入数组后尝试执行
this.fields = this.fields
。
Edit: some linters will guard against self-assignment.编辑:一些短绒将防止自我分配。 So, instead, we could pull from immutability patterns, and set using a new array, as shown below.
因此,相反,我们可以从不变性模式中提取,并使用新数组进行设置,如下所示。
export default class ConfigControlsComponent extends Component {
@tracked fields = []
@tracked newFieldName = ''
@action addField() {
// add this line
this.fields = [...this.fields, {
name: this.newFieldName
}];
}
}
If you are trying to use tracked
with an object instead of an array, you have two options:如果您尝试使用对象而不是数组
tracked
,则有两种选择:
First, you could create a class where all the properties on the object are 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}`;
}
}
Or, second, you could use the same "reset" approach as the array example above.或者,其次,您可以使用与上面的数组示例相同的“重置”方法。
Arrays are not automatically tracked if one of their element change.如果数组元素之一发生更改,则不会自动跟踪数组。 You cannot do:
你不能这样做:
this.fields.push({
name: this.newFieldName
})
But they get tracked if you change the whole array, using the spread operator for example:但是,如果您更改整个数组,例如使用扩展运算符,它们会被跟踪:
this.fields = [...this.fields, {name: this.newFieldName}]
Or eventually you can use EmberArray , see https://guides.emberjs.com/release/in-depth-topics/autotracking-in-depth/#toc_arrays或者最终您可以使用EmberArray ,请参阅https://guides.emberjs.com/release/in-depth-topics/autotracking-in-depth/#toc_arrays
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.