从Angular服务中删除对象

3

我有一个Angular 2应用中的服务events.service.ts

const EVENTS = {
  1512205360: {
    event: 'foo'
  },
  1511208360: {
    event: 'bar'
  }
}

@Injectable()
export class EventsService {
  getEvents() {
    return EVENTS;
  }
  deleteEvent(timestamp) {
    delete EVENTS[timestamp];
  }
}

我有一个home组件,在其ngOnInit钩子中调用此服务的getEvents方法:

getEvents(): void {
    this.events = this.eventsService.getEvents();
    this.eventKeys = Object.keys(this.events);
}

ngOnInit(): void {
    this.getEvents();
}

home组件的模板简单地循环遍历事件并将它们打印出来,每个事件旁边都有一个delete图标:

<event *ngFor="let eventKey of eventKeys" [timestamp]="eventKey" [title]="events[eventKey].event"></event>

这是“事件”组件:

event

@Component({
  selector: 'event',
  templateUrl: './event.component.html',
  providers: [EventsService]
})
export class EventComponent {
  @Input() timestamp: string;
  @Input() title: string;
  constructor(private eventsService: EventsService) { }

  deleteEvent(timestamp) {
    this.eventsService.deleteEvent(timestamp);
  }
}

点击“删除”图标会调用“events”服务中的“deleteEvent”方法。我的问题是,当我点击“删除”图标时,虽然我可以看到事件已被删除(通过“console.logging”“EVENTS”对象),但“home”组件没有更新并显示以下错误:
“无法读取未定义的属性'event'”。

主页组件因错误而未更新。您的解释不足以检测此错误。 - omeralper
请展示您的模板代码。 - Daniel Kucal
你需要在服务中设置一个主题,比如一个共享服务,它将通知组件的更改。 - Rahul Singh
谢谢Rahul-你有另一个链接吗?我点那个连接出现了空白页面。 - GluePear
@DanielKucal,我已经更新了问题并添加了更多代码。 - GluePear
1个回答

2
重点是HomeComponent.eventKeys数组没有与HomeComponent.events对象连接,而这个对象与EVENTS连接。你通过Object.keys()HomeComponent中的启动时设置了HomeComponent.eventKeys数组一次。所有对HomeComponent.events(以及EVENTS)的操作都不影响HomeComponent.eventKeys数组。因此,ngFor继续跟踪最初的关键字数组并在不存在的events项上崩溃。
有很多可能的解决方案,但主要思路是将HomeComponent.eventKeysEVENTS同步。例如,可以通过从HomeComponent传递删除方法到EventComponent并在删除后重新计算eventKeys数组来实现这一点。
// HomeComponent
deleteEvent(timestamp) {
  this.eventsService.deleteEvent(timestamp);
  this.getEvents();
}

更新

我刚刚为这种情况创建了一个plunk演示,欢迎使用:https://plnkr.co/edit/ogfmEY?p=preview


很好的诊断。但是,如果我不在“home”组件的新“deleteEvent”方法中添加“this.events = this.eventsService.getEvents()”,我会收到一个错误:“无法将未定义或空值转换为对象”。 - GluePear
如果我添加那行代码,我会得到与我的原始问题相同的错误。 - GluePear
刚刚添加了 this.getEvents(); 到答案中。我相信,从这一点上可以找到更优雅的解决方案。 - dhilt
我无法使其正确,因为您的解决方案不起作用。如果您删除您的解决方案,我认为您第一段中的诊断已足以标记此正确。 - GluePear
@GluePear 我已经更新了答案,并提供了一个可运行的演示,涵盖了这个问题。由于Angular 4基础设施的复杂性,这并不容易。所以解决方案是有效的,你可以看到。 - dhilt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接