最近我用Relay
. 我用两种方法做到了。其中一个不起作用,第二个起作用。从最终用户的角度来看,它们看起来都具有相同的功能。简而言之,该任务几乎是一个通用的递归数据获取,并在下一级展开获取。
第一种方式:
设置继电器变量后获取数据expand
。它是通过递归片段组合制成的。主要部分是这样的:
const CategoryItemContainer = Relay.createContainer(CategoryItem, {
initialVariables: {
expanded: false,
},
fragments: {
category: (variables) => Relay.QL`
fragment on Category {
id
name
hasChildren
${CategoryItemSubcategoryListContainer.getFragment('categories').if(variables.expanded)}
}
`,
},
});
const CategoryItemSubcategoryListContainer = Relay.createContainer(CategoryItemSubCategoryList, {
fragments: {
categories: () => Relay.QL`
fragment on Category {
categories(first: 10000) {
edges {
node {
${CategoryItemContainer.getFragment('category')}
}
}
}
}
`,
},
});
这样,它应该Relay.RootContainer
只被调用一次。它对我不起作用,但我知道其他人实现了它并且一切正常(这是另一篇文章的主题)。
第二种方式:
第二种方法对我来说很容易。我不使用Relay
变量,但我
Relay.Renderer
会根据 UI 组件的状态调用下一级递归。像这样:
{this.state.hasOwnProperty(category.id) ? // <- changing the state triggers the recursion
<Relay.Renderer
Container={CategoryItemSubCategoryListContainer}
queryConfig={new CategoryRoute({ id: category.id })}
environment={Relay.Store}
render={({ done, error, props, retry, stale }) => {
if (error) {
return 'Error';
} else if (props) {
return <CategoryItemSubCategoryListContainer {...props}
maxLevel={maxLevel}
currentLevel={currentLevel + 1}
activeCats={this.props.activeCats}
elementSelectedCallback={elementSelectedCallback}/>;
}
return (
<ul className="dropdown-menu" aria-labelledby="dLabel">
<li>
<div className="list-group-item"><p className="text-center"><img src="img/ajax-loader.gif"/></p></div>
</li>
</ul>
);
}}
/> : ''}
这就像我预期的那样工作。此外,我每次都有一个很好的加载器图标用于下一个级别。
所以,有了这个,我有三个问题:
首先
这些方法中的任何一种是可取的吗?也许在我不知道的地方有缺点?我想了解这一点,因为我正在
Relay
向我的公司介绍,我愿意用
React
and替换所有遗留前端Relay
。
第二
在某个时间点,用户将从这个递归分类器中选择一个类别,我将不得不获取导致当前级别的数据的完整路径。我的意思是,如果用户在层次结构的第 3 级选择一个类别,我必须返回这些数据:
[root cat id, root cat name],
[level 1 cat id, level 1 cat name],
[level 2 cat id, level 2 cat name]
因此,当我在级别 2 捕获组件内部拾取事件时,如何从根类别中获取完整路径Relay
?我认为我可以使用一些Relay
API 从商店获取它们?还是我必须自己实现这家商店?
第三
正如我在第二种实现方式中所说的,有一个很好的功能,每次Relay.Renderer
调用时我都会得到加载微调器。如何以第一种方式完成?我的意思是在第一种方式中,数据获取隐藏在片段组合中,并且由setVariables
. 我应该在方法之前触发微调器,然后在唯一的setVariables
方法中将其关闭吗?但是似乎我必须为渲染容器创建一个全局存储微调器的状态..我在这里很困惑..onReadyStateChange
Relay.RootContainer