首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Apollo,我如何区分新创建的对象?

使用Apollo,我如何区分新创建的对象?
EN

Stack Overflow用户
提问于 2017-02-20 08:46:47
回答 2查看 229关注 0票数 1

我的用例如下:

我有一个使用GraphQL查询获取的评论列表。当用户写一条新评论时,它会使用GraphQL变异来提交。然后我使用updateQueries将新注释追加到列表中。

在UI中,我想突出显示新创建的注释。我试图在mutationResult中的新注释上添加一个属性isNew: true,但Apollo在将其保存到存储之前删除了该属性(我假设这是因为在gql查询中没有请求isNew字段)。

有什么方法可以做到这一点吗?

EN

回答 2

Stack Overflow用户

发布于 2017-02-20 16:28:22

取决于你所说的“新创建的对象”是什么意思。如果它是基于身份验证的应用程序,用户可以登录,您可以将评论的create_date与用户的某个last_online日期进行比较。如果用户没有被强制创建账号,您可以将此类信息存储在本地存储或cookie中(用户上次访问网站的时间)。

另一方面,如果你想实时更新评论列表,我建议你看看使用websocketsgraphql-subscriptions。它通过使用pub-sub机制为您的用户界面提供了反应性。简单的用例--每当有新的评论被添加到帖子中时,每个用户/浏览者都会收到通知,评论可以被添加到评论列表中,并以你想要的方式突出显示。

为了实现这一点,您可以创建一个名为newCommentAddedsubscription,客户端将订阅该the,并且每次创建新评论时,应用程序的server端都会通知(publish)这一点。

这种情况的简单实现可能如下所示

代码语言:javascript
运行
复制
const Subscription = new GraphQLObjectType({
    name: 'Subscription',
    fields: {
        newCommentAdded: {
            type: Comment, // this would be your GraphQLObject type for Comment
            resolve: (root, args, context) => {
                return root.comment;
            }
        }
    }
});


// then create graphql schema with use of above defined subscription
const graphQLSchema = new GraphQLSchema({
    query: Query, // your query object
    mutation: Mutation, // your mutation object
    subscription: Subscription
});

上面的部分只是graphql-js部分,但是需要创建一个使用PubSub机制的SubscriptionManager

代码语言:javascript
运行
复制
import { SubscriptionManager, PubSub } from 'graphql-subscriptions';

const pubSub = new PubSub();

const subscriptionManagerOptions = {
    schema: graphQLSchema,
    setupFunctions: {
        newCommentAdded: (options, args) => {
            newCommentAdded: {
                 filter: ( payload ) => {
                     // return true -> means that  the subscrition will be published to the client side in every single case you call the 'publish' method
                     // here you can provide some conditions when to publish the result, like IDs of currently logged in user to whom you would publish the newly created comment
                     return true;
            }
        }
    },
    pubsub: pubSub
});

const subscriptionManager = new SubscriptionManager(subscriptionManagerOptions);

export { subscriptionManager, pubSub };

最后一步是在必要时通过上面创建的SubscriptionManager实例将新创建的注释publish到客户端。您可以在创建新注释的突变方法中或在需要的任何地方执行此操作

代码语言:javascript
运行
复制
// here newComment is your comment instance
subscriptionManager.publish( 'newCommentAdded', { comment: newComment } );

为了使用websockets实现pub-sub机制,有必要在主服务器旁边创建这样一个服务器。您可以使用subscriptions-transport-ws模块。

这样的解决方案最大的优点是它在你的应用程序中提供了反应性(应用于评论、列表、帖子等的实时更改)。我希望这对于您的用例来说是一个很好的选择。

票数 0
EN

Stack Overflow用户

发布于 2017-02-21 08:34:15

我可以看到有几种方法可以做到这一点。您说得对,Apollo将剥离isNew值,因为它不是您的模式的一部分,也不在查询选择集中列出。我喜欢将由apollo管理的服务器数据和前端应用程序状态分开,前端应用程序状态适合使用redux/flux,或者更简单地在组件状态下管理它。

Apollo让你可以选择提供你自己的redux商店。您可以允许apollo管理它的数据获取逻辑,然后在它旁边管理您自己的前端状态。这里有一篇文章讨论了如何做到这一点:http://dev.apollodata.com/react/redux.html

如果您正在使用React,则可以使用组件生命周期挂钩来检测何时出现新注释。这可能有点麻烦,但您可以使用componentWillReceiveProps将新的评论列表与旧的评论列表进行比较,确定哪些是新的,将它们存储在组件状态中,然后使用setTimeout在一段时间后使它们无效。

代码语言:javascript
运行
复制
componentWillReceiveProps(newProps) {

  // Compute a diff.
  const oldCommentIds = new Set(this.props.data.allComments.map(comment => comment.id));
  const nextCommentIds = new Set(newProps.data.allComments.map(comment => comment.id));
  const newCommentIds = new Set(
    [...nextCommentIds].filter(commentId => !oldCommentIds.has(commentId))
  );
  this.setState({
    newCommentIds
  });

  // invalidate after 1 second
  const that = this;
  setTimeout(() => {
    that.setState({
      newCommentIds: new Set()
    })
  }, 1000);
}

// Then somewhere in your render function have something like this.
render() {
  ...
  {
    this.props.data.allComments.map(comment => {
      const isNew = this.state.newCommentIds.has(comment.id);
      return <CommentComponent isNew={isNew} comment={comment} />
    })
  }
  ...
}

上面的代码是即兴的,所以你可能需要尝试一下。希望这能有所帮助:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42334805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档