分类筛选功能异常
========

#### 问题现象

点击打开筛选界面，有分类和主题两个部分，主题可以多选，若没有选择主题，则分类只能选择一个。但是选择主题后，多选分类，此时再将选择的主题全部取消，分类还是会保存多选状态。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/10/v3/lFm-Mq4ITXaMPRVuT484AQ/zh-cn_image_0000002658924029.png?HW-CC-KV=V1&HW-CC-Date=20260709T133929Z&HW-CC-Expire=86400&HW-CC-Sign=15C9D8AC8D2470C2112CEC4B6556ABF04BB4EFE1B04F599DF026E0713EDBD642 "点击放大")

#### 背景知识

[模态转场](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-modal-transition)是新的界面覆盖在旧的界面上，旧的界面不消失的一种转场方式，常用于实现筛选框、侧边栏等功能。

#### 问题定位

1.  使用DevEco Testing中的UIViewer工具，查看筛选界面的布局，发现筛选界面使用[半模态转场](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-sheet-transition)实现，内容使用[线性布局](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-layout-development-linear)以及[Grid组件](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-grid)实现，不涉及与H5页面的交互。
2.  根据问题现象，推测在取消全部主题的场景中未重置分类。
3.  排查代码，查看是否有单独记录分类和主题两个内容的选择状态，并在主题选择为空时将分类的选择也重置。

#### 分析结论

当主题的选择内容从有变无时，未对分类选项做重置操作，导致取消主题的所有选择后，分类仍为多选状态。

#### 修改建议

在点击主题选项时添加判断，若主题选择为空并且分类为多项状态，则将筛选重置，示例代码如下：

import { PromptAction, UIContext } from '@kit.ArkUI';
@ObservedV2
  _// 观察点击事件_
class textFont { _// 创建一个文本类_
  tex: number = 0;
  @Trace isClick: boolean = false; _// 记录是否被点击_

  constructor(tex: number) {
    this.tex = tex; _// 初始化文本值_
  }
}

@Entry
@Component
struct BindSheetSelect {
  @State isShowSheet: boolean = false; _// 控制筛选框显隐_
  selectList: Array<textFont> = \[\]; _// 分类列表_
  themeList: Array<textFont> = \[\]; _// 主题列表_
  @State selectNum: number = 0; _// 选择的分类数量_
  @State themeNum: number = 0; _// 选择的主题数量_
  uiContext: UIContext = this.getUIContext();
  promptAction: PromptAction = this.uiContext.getPromptAction();

  aboutToAppear(): void {
    for (let i = 0; i < 4; i++) { _// 初始化列表_
      this.selectList.push(new textFont(i));
      this.themeList.push(new textFont(i));
    }
  }

  @Builder
  SheetBuilder() {
    Column() {
      Column({ space: 30 }) {
        Row() {
          Text('分类')
        }
        .width('100%')
        .justifyContent(FlexAlign.Start)
        .padding({
          left: 30
        })

        Grid() {
          ForEach(this.selectList, (item: textFont) => {
            GridItem() {
              Row() {
                Text(item.tex.toString())
                  .fontColor('#0A59F7')
              }
              .backgroundColor('#0d000000')
              .borderWidth(item.isClick ? 1 : 0)
              .borderColor('#0A59F7')
              .opacity(item.isClick ? 1 : (this.selectNum ? (this.themeNum ? 1 : 0.4) : 1))
              .borderRadius(20)
              .width(100)
              .height(30)
              .justifyContent(FlexAlign.Center)
            }
            .onClick(() => { _// 切换点击状态_
              if (!item.isClick) { _// 若没有被点亮_
                if (!this.selectNum) { _// 没有选择过分类，可以选一个_
                  item.isClick = true;
                  this.selectNum++;
                } else {
                  if (this.themeNum) { _// 选了主题，可以多选分类_
                    item.isClick = true;
                    this.selectNum++;
                  }
                }
              } else { _// 若被点亮了,则取消点亮状态_
                item.isClick = false;
                this.selectNum--;
              }
            })
          })
        }
        .width('100%')
        .height(80)
        .columnsTemplate('1fr 1fr 1fr')
        .rowsGap(20)

        Row() {
          Text('主题')
        }
        .width('100%')
        .justifyContent(FlexAlign.Start)
        .padding({
          left: 30
        })

        Grid() { _// 使用网格容器选项列表_
          ForEach(this.themeList, (item: textFont) => {
            GridItem() {
              Row() {
                Text(item.tex.toString()) _// 选项内容_
                  .fontColor('#0A59F7')
              }
              .backgroundColor('#0d000000')
              .borderWidth(item.isClick ? 1 : 0)
              .borderColor('#0A59F7')
              .borderRadius(20)
              .width(100)
              .height(30)
              .justifyContent(FlexAlign.Center)
            }
            .onClick(() => {
              if (item.isClick) { _// 判断选项是否被点击_
                item.isClick = !item.isClick;
                this.themeNum--; _// 主题选择数量_
                if (this.themeNum === 0 && this.selectNum > 1) { _// 当主题选项为空，且分类为多选，则将所有选项全部重置_
                  this.selectNum = 0; _// 清空分类选项_
                  for (let i = 0; i < 4; i++) { _// 重置所有内容_
                    this.selectList\[i\].isClick = false;
                    this.themeList\[i\].isClick = false;
                  }
                }
              } else {
                item.isClick = !item.isClick;
                this.themeNum++;
              }

            })
          })
        }
        .width('100%')
        .height(80)
        .columnsTemplate('1fr 1fr 1fr')
        .rowsGap(20)

        Row() {
          Button('确定')
            .onClick(() => {
              if (!this.selectNum) {
                this.promptAction.openToast({
                  message: '未选分类'
                });
              } else if (!this.themeNum) {
                this.promptAction.openToast({
                  message: '未选主题'
                });
              } else {
                this.isShowSheet = false;
              }
            })

          Button('取消')
            .onClick(() => {
              this.isShowSheet = false;
            })
        }
        .width('100%')
        .height('15%')
        .justifyContent(FlexAlign.SpaceEvenly)
      }
    }
    .width('100%')
    .height('100%')
  }

  @Builder
  titleBuilder() {
    Column() {
      Text('筛选')
    }
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }

  build() {
    Column() {
      Button('点击打开筛选框')
        .onClick(() => {
          this.isShowSheet = !this.isShowSheet;
        })
        .bindSheet($$this.isShowSheet, this.SheetBuilder(), {
          detents: \[SheetSize.MEDIUM, SheetSize.LARGE, 600\],
          preferType: SheetType.BOTTOM,
          title: this.titleBuilder(),
          showClose: false,
          dragBar: false,
          backgroundColor: Color.White
        })
    }.width('100%').height('100%')
    .justifyContent(FlexAlign.Center)
  }
}