为什么我的跟踪阵列在 Ember Octane 中没有更新?

han*_*ars 5 ember.js ember.js-3

我正在试用 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}}
Run Code Online (Sandbox Code Playgroud)

和组件:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

console.log节目的阵列添加到它的新对象,并且fields阵列被跟踪,但是当我按一下按钮没有什么变化。

han*_*ars 5

当您使用tracked数组时,您需要“重置”数组,以便 Ember 注意到发生了变化。this.fields = this.fields在将新对象推入数组后尝试执行。

编辑:一些短绒将防止自我分配。因此,相反,我们可以从不变性模式中提取,并使用新数组进行设置,如下所示。

export default class ConfigControlsComponent extends Component {
  @tracked fields = []
  @tracked newFieldName = ''

  @action addField() { 
    // add this line
    this.fields = [...this.fields, {
      name: this.newFieldName
    }]; 
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您尝试使用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}`;
  }
}
Run Code Online (Sandbox Code Playgroud)

或者,其次,您可以使用与上面的数组示例相同的“重置”方法。

  • 您也可以执行 `this.fields = [...this.fields, { name: this.newFieldName }]` 。 (4认同)
  • `pushObject` 而不是 `push` 应该可以正常工作。这通知 ember 重新渲染。 (4认同)