如何过滤 ResourceList 中的项目

问题描述

我正在尝试按标签过滤我的 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))
}