在任何地方,您都可以看到subscribe here, subscription there, unsubscribe here, unsubscribe there
。我问,如果可以在组件中直接使用服务属性,我们需要这些样板代码做什么?
@injectable()
export class MyService {
public logItems: Log[] = [];
getLatestLogItems() {
return this.httpService.GetLatestLogItems() // some http service
.subscribe(
(items) => {
this.logItems = items;
},
...
);
}
}
,然后在组件中:
@Component({
selector: 'app-logs',
template: `<ul>
<li *ngFor="let log of myService.logItems"> {{ log | json}} </li>
</ul> `
})
export class MyComponent implements OnInit {
constructor(public myService: MyService) { }
ngOnInit() {
this.myService.getLatestLogItems();
}
如果要刷新数据,只需再次调用getLatestLogItems()
。
我在这里想念什么?为什么根本需要学科?
答案 0 :(得分:0)
您应该订阅组件并从服务中返回可观察到的
@injectable()
export class MyService {
public logItems: Log[] = [];
getLatestLogItems(): Observable<any> {
return this.httpService.GetLatestLogItems() // some http service
}
}
在组件中:
ngOnInit() {
this.myService.getLatestLogItems().subscribe(response => {console.log(response)})
}
答案 1 :(得分:0)
要解决此问题,您需要了解Observable
和Observer
的概念。
Observables
不返回任何内容,而是发出项目,以便Observers
可以订阅。这样Observer
随时准备在Observable将来的任何时间做出适当的反应。
有关更多信息,请参阅ReactiveX documentation。
是的,订阅和取消订阅有时看起来很令人沮丧,但是在您的代码中:
getLatestLogItems() {
return this.httpService.GetLatestLogItems().subscribe((items) => {
this.logItems = items;
});
}
getLatestLogItems
不返回任何内容。
答案 2 :(得分:0)
根据您的用例,通常我认为做上面提到的方式是一个坏主意:
潜在的内存泄漏:何时取消订阅?反复调用getLatestLogItems
可能会导致内存泄漏。虽然在这种情况下,可能不是因为httpClient处理了此问题,但是其他可以观察到的方法也可能。
值更新未跟踪:您的myService.logItems
值未跟踪。如果您在同一页面中有多个相同的组件(例如ngFor),或者在其他页面中使用了该组件+您的服务是单例的(大多数情况下是这样),则可能会导致意外结果。在此处查看简单的演示:https://stackblitz.com/edit/so-rxjs-test。该值未在模板中正确更新。
关注点分离:服务应在组件中是私有的。您正在向公众公开服务。这不是一个好习惯。这是因为服务(另一层)用于代码分离。如果您按照上述方式操作,则不妨直接在组件中编写getLatestLogItems
函数。
如果您不喜欢样板代码,则可以考虑通过调用observable
将所有promise
转换为.toPromise
。这样,您无需.subscribe
和.unsubscribe
,但您需要.then
或async await
...
我希望这为样板提供了一些理由。如果您正在使用其他框架(例如React或Vue),甚至只是没有rxjs的jquery,则对于所有api调用,项目4都是不可避免的(需要.then
或异步等待)。
答案 3 :(得分:0)
我不会说您的代码是错误的。 Http请求会自动退订,因此不会出现内存泄漏。您还可以控制何时发生请求。在代码方面,我看不到任何问题,但也许我遗漏了一些东西。
我仍然不会使用此模式。我的观点是服务将开始定义您的组件。感觉有点奇怪。您还限制了RxJ的使用。每个组件都应按其认为适合该特定组件的方式处理api调用。
但是,我没有看到任何功能上的损失,但是我确实看到黑客入侵了您的代码。因此,这并不可怕,但是在服务方面却有点自私。让组件决定如何使用数据。