Apollo - Angular 应用程序中子组件的多个 graphql 订阅
Posted
技术标签:
【中文标题】Apollo - Angular 应用程序中子组件的多个 graphql 订阅【英文标题】:Apollo - multiple graphql subscriptions from child components in Angular app 【发布时间】:2021-10-13 18:01:17 【问题描述】:一般建议(在 Apollo 文档中)是在子组件中创建小的、集中的查询。
所以我们有几个这样的查询,它们都是我们监听值变化的“实时”查询。
我们还有一个 graphql 订阅,用于更新这些查询读取的部分缓存。
所以每次订阅发送更新时,查询都会自动更新。
这很好用,但我不确定我应该在哪里订阅。
这就是我们现在正在做的事情:
class AComponent
ngOnInit()
// Multiple instances of AComponent watch the same query.
// Works great - one request is sent to the server and
// all the others use the cache
this.queryService1.watch()...
// And we subscribe to a subscription that might update the cache
// and cause the query to update
this.subscription.subscribe();
既然AComponent
有多个实例,可以全部订阅订阅吗?
【问题讨论】:
这看起来像是一些商店管理的用例,例如 NgRx。但这需要一些剧烈的重构。也许可以使用一些与 NgRx 具有相似和简化逻辑的服务。如果需要,您可以注入服务,并且您不会像那样使用它来耦合子组件和父组件。 @dallows 看不出它是如何解决问题的。问题仍然存在,在哪里订阅订阅。在一个地方或可以在多个地方完成而无需开销 这基本上是 NgRx 所做的。你有一个单一的事实来源,你在每个需要状态切片的组件中订阅它。所以组件中的多个订阅是没有问题的。只是代替父/***组件使用服务。 但我问的是订阅 graphql 订阅。换句话说,“激活”订阅(要求服务器向我们发送更新)。我不需要 NgRX 作为单一的事实来源,因为我已经有了 Apollo 缓存。 【参考方案1】:由于您没有提供任何代码,我只是在猜测,但我会在独立服务中“激活”订阅,该服务可以在某些***组件中初始化。如果您想在组件中访问它,请将其作为标准服务注入。
// app.component
export class AppComponent implements OnInit
constructor(private apolloQueryService: ApolloQueryService)
ngOnInit()
this.apolloQueryService.initialize();
//...
// ApolloQueryService
// I have no experience with Apollo, this is just to illustrate
@Injectable(
providedIn: 'root',
)
export class ApolloQueryService
apolloSub$;
constructor(private apollo: Apollo)
initialize(): void
this.apolloSub$ = this.appolo.someQuery.subscribe();
// add others if necessary
//...
根据您关于可观察拆分的另一个问题判断,此服务可用于公开部分查询。
【讨论】:
感谢您在我的问题上投入时间:-)。你的回答从几个方面来说是错误的。首先,如果您想要的只是执行查询的服务,那么您将扩展 Apollo 的Query
类。其次,我问的是 graphql 订阅,而不是查询。第三,我希望你不会觉得它冒犯,但如果你没有 Apollo 的经验,那么你可能无法回答这个问题。我非常熟悉 Angular、NgRX 等。这个问题是关于与 Apollo 合作的正确方式。
未采纳,但正如我所说,由于您一开始没有提供任何代码,因此很难弄清楚您要实现什么【参考方案2】:
在测试了我的解决方案后,我发现每次订阅订阅都会收到一个事件。
在我们的例子中,我们多次订阅同一个订阅并收到多个相同的 websocket 消息。
为了解决这个问题,我们现在将订阅包装在一项服务中,以确保我们只订阅一次:
class PostsUpdateService
private subscribed: boolean;
constructor(private postsSubscription: Subscription<Post>)
subscribe()
if (!this.subscribed)
this.subscribed = true;
this.postsSubscription.subscribe().subscribe();
在我们的例子中,我们可以从不退订,因为我们总是至少有 1 个实时订阅。
【讨论】:
以上是关于Apollo - Angular 应用程序中子组件的多个 graphql 订阅的主要内容,如果未能解决你的问题,请参考以下文章
Apollo Angular 无法从 GraphQL/MongoDB 获取数据
apollo.watchQuery 堆栈/重复 = 性能问题?
Angular Apollo GraphQL watchQuery 与订阅