问题描述
我正在尝试按标签过滤我的 ResourceList 中的 ResourceItem。例如,如果用户搜索标签“体育”,则应返回所有带有此标签的项目。
我一直在使用 this example 来生成它,但是当用户输入要过滤的标签时,它实际上没有任何功能。
到目前为止,这是我的代码,其中我没有取回任何项目:
const GetProductList = () => {
// State setup
const [taggedWith,setTaggedWith] = useState(null);
const [queryValue,setQueryValue] = useState(null);
// Handled TaggedWith filter
const handleTaggedChange = useCallback(
(value) => setTaggedWith(value),[],);
const handleTaggedRemove = useCallback(() => setTaggedWith(null),[]);
const handleQueryRemove = useCallback(() => setQueryValue(null),[]);
const handleFilterClear = useCallback(() => {
handleTaggedRemove();
handleQueryRemove();
},[handleQueryRemove,handleTaggedRemove]);
const filters = [
{
key:'taggedWith',label:'Tagged With',filter: (
<TextField
label="Tagged With"
value={taggedWith}
onChange={handleTaggedChange}
labelHidden
/>
),shortcut: true,}
];
const appliedFilters = !isEmpty(taggedWith)
? [
{
key: 'taggedWith',label: disambiguateLabel('taggedWith',taggedWith),onRemove: handleTaggedRemove,},]
: [];
const filterControl = (
<Filters
queryValue={queryValue}
filters={filters}
appliedFilters={appliedFilters}
onQueryChange={setQueryValue}
onQueryClear={handleQueryRemove}
onClearall={handleFilterClear}
children={() => {
<div>Hello World</div>
}}
>
<div>
<Button onClick={() => console.log('New Filter Saved')}>Save</Button>
</div>
</Filters>
)
// Execute GET_PRODUCTS GQL Query
const { loading,error,data } = useQuery(GET_PRODUCTS);
if (loading) return "Loading products...";
if (error) return `Error = ${error}`;
// Return dropdown menu of all products
return (
<Frame>
<Page>
<Layout>
<Layout.Section>
<displayText size="large">WeBuy Valuation Tool</displayText>
</Layout.Section>
<Layout.Section>
<Card>
<Card.Section>
<div>
<Card>
<ResourceList
resourceName={{singular: 'product',plural: 'products'}}
items={data ? data.products.edges : ""}
renderItem={renderItem}
filterControl={filterControl}
>
</ResourceList>
</Card>
</div>
</Card.Section>
</Card>
</Layout.Section>
</Layout>
</Page>
</Frame>
)
function renderItem(item) {
const { id,title,images,tags } = item.node;
const media = (
<Thumbnail
source={ images.edges[0] ? images.edges[0].node.originalSrc : '' }
alt={ images.edges[0] ? images.edges[0].node.altText : '' }
/>
);
const resourceItem = (
<ResourceItem
id={id}
accessibilityLabel={`View details for ${title}`}
media={media}
>
<Stack>
<Stack.Item fill>
<h3><TextStyle variation="strong">{title}</TextStyle></h3>
<h2>{tags}</h2>
</Stack.Item>
<Stack.Item>
<AddMetafield id={id} />
<DeleteMetafield id={id} />
</Stack.Item>
</Stack>
</ResourceItem>
);
tags ? tags.forEach(tag => {
if (tag == "Sports") {
console.log("has tag")
return resourceItem
}
}) : console.log("Return")
}
function disambiguateLabel (key,value) {
switch(key) {
case 'taggedWith' :
return `Tagged with ${value}`;
default:
return value;
}
}
function isEmpty(value) {
if (Array.isArray(value)) {
return value.length === 0;
} else {
return value === '' || value == null;
}
}
}
解决方法
我找不到任何关于如何实现它的文档,我希望它是内置的,但我最终做了这样的事情:
//add "filter.apply" function to the filter object
const filters = [{...apply:(c:Item)=>...},isApplied=...]
const appliedFilters = filters.filter(f=>f.isApplied);
let filteredItems = pageData.Items;
for (const filter of appliedFilters){
filteredItems = filteredItems.filter(filter.apply)
}
if(queryValue && queryValue.length > 0){
filteredItems = filteredItems.filter((c:FBComment)=>c.text.includes(queryValue))
}