【问题标题】:Writing Fragments for Polymorphic Associations in RelayJS and GraphQL在 RelayJS 和 GraphQL 中为多态关联编写片段
【发布时间】:2017-11-04 07:12:18
【问题描述】:

我的后端架构有一个模型 Request,它使用多态关联,这样几个不同的模型都有多个请求,Request 可以属于这些不同模型中的任何一个。

我有一个 React 组件 RequestList,我希望能够在它的任何潜在父模型中使用它。

这里有一些示例代码:

FooShowView.js

class FooShowView extends Component {
  render() {
    return (
      <RequestList router={this.props.router} />
    )
  }
}

export default Relay.createContainer(ShowView, {
  initialVariables: {
    FooId: null
  },
  fragments: {
    viewer: (variables) => {
      return Relay.QL`
        fragment on Viewer {
          Foo(id: $FooId) {
            id${ RequestList.getFragment('Foo') }
          }
        }`
      `
    }
  }
});

RequestList.js

class RequestList extends Component {

  renderRows = () => {
    return this.props.requests.edges.map(edge => edge.node).map((intReq, i) => {
      return (
        <RequestRow
          request={ intReq }
          key={ i }
        />
      );
    });
  }

  render() {
    return (
      <Table>
        { this.renderRows() }
      </Table>
    );
  }
};

export default Relay.createContainer(RequestList, {
  fragments: {
    foo: () => Relay.QL`
      fragment on Foo {
        requests(first: 10) {
          edges {
            node {
              ${ RequestRow.getFragment('request') }
            }
          }
        }
      }
    `,
  }
})

问题是现在要为Request 的另一个父母呈现RequestTable,比如在BarShowView 中,我需要向RequestList 添加一个新片段:

bar: () => Relay.QL`
  fragment on Bar {
    requests(first: 10) {
      edges {
        node {
          ${ RequestRow.getFragment('request') }
        }
      }
    }
  }
`,

然后 Relay 会发出警告,我需要将 bar 和 foo 作为道具提供给我的列表,即使它与当前视图无关。

由于Request 在我的架构中与大约 8 个不同的模型相关联,这很快就会变得不合理。

创建可重用反应组件的正确方法是什么?该组件将呈现我正在查看的任何记录的多态子级?

【问题讨论】:

    标签: reactjs relayjs graphql-js


    【解决方案1】:

    我最终所做的(以防有人遇到这种情况)只是将RequestList 片段放在根目录上并传入变量,因此它只查询适当的关联记录。比编写六个片段要简单得多。所以我的 createContainer 调用现在看起来像:

    export default Relay.createContainer(RequestList, {
      initialVariables: {
        fooId: null,
        barId: null
      }
      fragments: {
        viewer: () => Relay.QL`
          fragment on Viewer {
            requests(
              first: 10,
              fooId: $fooId,
              barId: $barId
            ) {
              edges {
                node {
                  ${ RequestRow.getFragment('request') }
                }
              }
            }
          }
        `,
      }
    })
    

    注意:如果您想知道为什么我要同时传递 fooID 和 barId 而不是“requestableType”和“requestableID”,那是因为我使用的 Elixir 不支持这种类型的多态性。

    【讨论】:

      猜你喜欢
      • 2021-05-06
      • 2017-05-01
      • 2016-01-08
      • 2019-03-09
      • 2020-04-30
      • 2018-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多