从数据源

时间:2017-04-23 11:28:09

标签: ember.js

在控制器内部,我有以下代码,

export default Controller.extend({
  session: service(),

  cards: {},

  init() {
    this._super(...arguments);

    const uid = this.get('session.data.authenticated.user.uid');

    const databaseRef = firebase.database()
      .ref(`cards/${uid}`);

    const cards = this.get('cards');

    databaseRef.on('child_added', data => {
      const card = data.val();
      this.set(`cards.${card.key}`, card);
    });

    databaseRef.on('child_changed', data => {
      const card = data.val();
      this.set(`cards.${card.key}`, card);
    });

    databaseRef.on('child_removed', data => {
      const card = data.val();
      const cards = this.get('cards');
      delete cards[card.key];
      this.set('cards', cards);
    });
  }

在我的模板中,

{{#each-in cards as |key card|}}
  {{card-item
    card=card
  }}
{{/each-in}}

cards对象中添加了新卡时,它工作正常。但是,当我使用delete this.get('cards')[card.key]从对象中删除卡时,列表不会重新呈现。

我已确认在触发child_removed事件后通过注销卡片状态来更改数据源。

我错过了什么吗?

更新

我可以通过重新分配一个深度克隆的cards对象来重新渲染模板,但这非常昂贵,因为整个卡片列表需要重新渲染。

databaseRef.on('child_removed', data => {
  const card = data.val();
  const cards = this.get('cards');
  delete cards[card.key];

  const cardsStr = JSON.stringify(cards);
  this.set('cards', JSON.parse(cardsStr));
});

2 个答案:

答案 0 :(得分:1)

您可以致电notifyPropertyChange

delete cards[card.key];
cards.notifyPropertyChange(card.key);

答案 1 :(得分:0)

  

{{#each-in}}帮助程序不会观察对传递给它的对象的属性更改。在上面的示例中,如果要在组件呈现后向组件的categories属性添加键,则模板不会自动更新。

     

为了在从对象添加,删除或更改属性后使组件重新呈现,您需要再次设置()组件上的属性,或者手动触发重新呈现组件组件通过rerender():

参考旧指南:https://guides.emberjs.com/v2.6.0/templates/displaying-the-keys-in-an-object/#toc_re-rendering

如果你在Component中,那么你可以拨打rerender,否则你可以像Lux提到的那样拨打notifyPropertyChange