为什么我的跟踪数组不会在 Ember Octane 中更新?
Why won't my tracked array update in Ember Octane?
我正在试用 Octane,出于某种原因,如果我在模板中显示数组并向其添加新对象,UI 不会更新。我做错了什么?
这是我的模板:
<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
数组,但单击按钮时没有任何变化。
当您对数组使用 tracked
时,您需要 "reset" 数组,以便 Ember 注意到已经发生了变化。将新对象推入数组后尝试执行 this.fields = this.fields
。
编辑:一些 linters 会防止自我分配。因此,相反,我们可以从 不变性 模式中提取,并使用新数组进行设置,如下所示。
export default class ConfigControlsComponent extends Component {
@tracked fields = []
@tracked newFieldName = ''
@action addField() {
// add this line
this.fields = [...this.fields, {
name: this.newFieldName
}];
}
}
如果您尝试将 tracked
用于对象而不是数组,您有两个选择:
首先,您可以创建一个 class 来跟踪对象的所有属性:
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}`;
}
}
或者,其次,您可以使用与上述数组示例相同的 "reset" 方法。
如果其中一个元素发生变化,则不会自动跟踪数组。
你不能这样做:
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
我正在试用 Octane,出于某种原因,如果我在模板中显示数组并向其添加新对象,UI 不会更新。我做错了什么?
这是我的模板:
<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
数组,但单击按钮时没有任何变化。
当您对数组使用 tracked
时,您需要 "reset" 数组,以便 Ember 注意到已经发生了变化。将新对象推入数组后尝试执行 this.fields = this.fields
。
编辑:一些 linters 会防止自我分配。因此,相反,我们可以从 不变性 模式中提取,并使用新数组进行设置,如下所示。
export default class ConfigControlsComponent extends Component {
@tracked fields = []
@tracked newFieldName = ''
@action addField() {
// add this line
this.fields = [...this.fields, {
name: this.newFieldName
}];
}
}
如果您尝试将 tracked
用于对象而不是数组,您有两个选择:
首先,您可以创建一个 class 来跟踪对象的所有属性:
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}`;
}
}
或者,其次,您可以使用与上述数组示例相同的 "reset" 方法。
如果其中一个元素发生变化,则不会自动跟踪数组。 你不能这样做:
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