在控制器内部,我有以下代码,
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));
});
答案 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。