HarmonyOS 使用TextPickerDialog.show方法onchange的时候修改range的参数怎么让弹窗中的内容也改变?

使用TextPickerDialog.show方法onchange的时候修改range的参数怎么让弹窗中的内容也改变?

比如地址选择器的实现,省份选择后市区列对应的内容需要改变。

demo实现:

interface btnParams {
  title: string;
  color: string
}

interface resultParams { value: Date; }

interface DatePickerParams {
  pattern?: string;
  titleBtn?: btnParams;
  leftBtn?: btnParams;
  rightBtn?: btnParams;
  maxDate?: number; // 最大日期时间戳
  minDate?: number; // 最小日期时间戳
  date?: number; // 当前显示日期时间戳
  callback?: (result: resultParams) => void;
}
const fieldMap: Record<string, string> = {
  'yyyy': 'year',
  'YYYY': 'year',
  'MM': 'month',
  'dd': 'day',
  'DD': 'day',
  'HH': 'hour',
  'hh': 'hour',
  'mm': 'minute',
  'ss':'second'
};


export async function SuiDatePicker(options: WosaifuncOptions) {

  let pickerParams: DatePickerParams = options.params as DatePickerParams;

  console.log('pickerParams',JSON.stringify(pickerParams))

  const fields = pickerParams.pattern?.split(/[- :]/).map(part => fieldMap[part]); // 根据 pattern 拆分字段
  const maxDate:Date = new Date(pickerParams.maxDate ? pickerParams.maxDate* 1000 : '');
  const minDate:Date = new Date(pickerParams.minDate ? pickerParams.minDate*1000 : '1970-1-1');
  const selDate:Date = new Date(pickerParams.date ? pickerParams.date*1000 : '');

  console.log('selDate',JSON.stringify(selDate))
  console.log('fields',JSON.stringify(fields))
  let selectedDate: Record<string, string> = {
    "year":selDate.getFullYear().toString(),
    "month": (selDate.getMonth() + 1).toString(),
    "day": selDate.getDate().toString(),
    "hour": selDate.getHours().toString(),
    "minute": selDate.getMinutes().toString(),
    "second": selDate.getSeconds().toString(),
  };

  let generateRange: Function = (min: number, max: number, current: number): string[]=> {
    let range:string[] = [];
    for (let i = min; i <= max; i++) {
      range.push(i+'');
    }
    return range;
  }

  let updateRanges: Function = (field: string, value: string) => {
    selectedDate[field] = value;

    if (field === 'year') {
      ranges.month = generateRange(1, 12, selectedDate.month);
      ranges.day = generateRange(1, getDaysInMonth(selectedDate.year, selectedDate.month), selectedDate.day);
    } else if (field === 'month') {
      ranges.day = generateRange(1, getDaysInMonth(selectedDate.year, selectedDate.month), selectedDate.day);
    }
  }

  let getDaysInMonth: Function = (year: number, month: number): number=>{
    return new Date(year, month, 0).getDate();
  }

  let formatSelectedDate = (selectedDate: Record<string, string>, pattern: string): string=>{
    const dateComponents: Record<string, string> = {
      'yyyy': selectedDate.year,
      'YYYY': selectedDate.year,
      'MM': selectedDate.month,
      'dd': selectedDate.day,
      'DD': selectedDate.day,
      'HH': selectedDate.hour,
      'hh': selectedDate.hour,
      'mm': selectedDate.minute,
      'ss':selectedDate.second
    };

    return pattern.replace(/yyyy|YYYY|MM|dd|DD|HH|hh|mm|ss/g, match => dateComponents[match]);
  }
  let getRanges = (date: Record<string, string>, minDate: Date, maxDate: Date):Record<string, string[]> => {
    return {
      "year": generateRange(minDate.getFullYear(), maxDate.getFullYear(), date.year),
      "month": generateRange(1, 12, date.month),
      "day": generateRange(1, getDaysInMonth(date.year, date.month), date.day),
      "hour": generateRange(0, 23, date.hour),
      "minute": generateRange(0, 59, date.minute),
      "second": generateRange(0, 59, date.second),
    };
  }


  let ranges: Record<string, string[]> = {
    "year": generateRange(minDate.getFullYear(), maxDate.getFullYear(), selectedDate.year),
    "month": generateRange(1, 12, selectedDate.month),
    "day": generateRange(1, 31, selectedDate.day),
    "hour": generateRange(0, 23, selectedDate.hour),
    "minute": generateRange(0, 59, selectedDate.minute),
    "second": generateRange(0, 59, selectedDate.second),
  };


  console.log('selectedDate',JSON.stringify(selectedDate))
  console.log('ranges', JSON.stringify(ranges))
  console.log(JSON.stringify(fields?.map((field) => ranges[field].indexOf(selectedDate[field].toString()))))

  TextPickerDialog.show({
    range: fields?.map((field) => ranges[field]) || [],
    selected: fields?.map((field) => ranges[field].indexOf(selectedDate[field].toString())) || [],
    canLoop: false,
    alignment: DialogAlignment.Bottom,
    offset: { dx: 0, dy: 0 },
    disappearTextStyle: { color: $r("app.color.color_N7"), font: { size: 15, weight: FontWeight.Lighter } },
    textStyle: { color: $r("app.color.color_N7"), font: { size: 15, weight: FontWeight.Normal } },
    selectedTextStyle: { color: $r("app.color.color_B"), font: { size: 18, weight: FontWeight.Bolder } },
    acceptButtonStyle: {
      fontColor: pickerParams.rightBtn?.color || $r("app.color.color_W"),
      fontSize: '16fp',
      backgroundColor: $r("app.color.color_Switch_Select")
    },
    cancelButtonStyle: {
      fontColor: pickerParams.leftBtn?.color|| $r("app.color.color_B"),
      fontSize: '16fp',
      backgroundColor: $r("app.color.color_N4")
    },
    onAccept: (value: TextPickerResult) => {
      console.log(JSON.stringify(value))
      if(typeof value.value == 'string'){

      }else{
        value.value.forEach((item,index)=>{
          selectedDate[fields?.[index.toString()]] = item;
          updateRanges(fields?.[index.toString()], item);
        })
      }
      console.log('selectedDate:', JSON.stringify(selectedDate),formatSelectedDate(selectedDate, pickerParams.pattern))
      options.callback && options.callback(new Date(formatSelectedDate(selectedDate, pickerParams.pattern)).getTime()/1000)
    },
    onChange: (value:TextPickerResult)=>{
      fields?.forEach((field, index) => {
        updateRanges(field, value.value[index]);
      });
      ranges = getRanges(selectedDate, minDate, maxDate);
    }
  });

}
HarmonyOS
2天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
Heiang

写了一个demo,修改demo里面的fruits,即可让弹窗中的内容也改变,demo如下:

@Entry
@Component
export struct TextPickerDialogExample {
  private select: number | number[] = 0
  // private fruits: string[] = ['apple1', 'orange2', 'peach3', 'grape4', 'banana5'];
  private fruits: string[] = ['apple1', 'orange2', 'peach3', 'grape4', 'banana5','banana6','banana7']
  @State v:string = '';

  build() {
    NavDestination(){
      Row() {
        Column() {
          Button("TextPickerDialog:" + this.v)
            .margin(20)
            .onClick(() => {
              TextPickerDialog.show({
                range: this.fruits,
                selected: this.select,
                disappearTextStyle: {color: Color.Red, font: {size: 15, weight: FontWeight.Lighter}},
                textStyle: {color: Color.Black, font: {size: 20, weight: FontWeight.Normal}},
                selectedTextStyle: {color: Color.Blue, font: {size: 30, weight: FontWeight.Bolder}},
                onAccept: (value: TextPickerResult) => {
                  // 设置select为按下确定按钮时候的选中项index,这样当弹窗再次弹出时显示选中的是上一次确定的选项
                  this.select = value.index
                  console.log(this.select + '')
                  // 点击确定后,被选到的文本数据展示到页面
                  this.v = value.value as string
                  console.info("TextPickerDialog:onAccept()" + JSON.stringify(value))
                },
                onCancel: () => {
                  console.info("TextPickerDialog:onCancel()")
                },
                onChange: (value: TextPickerResult) => {
                  console.info("TextPickerDialog:onChange()" + JSON.stringify(value))
                },
                onDidAppear: () => {
                  console.info("TextPickerDialog:onDidAppear()")
                },
                onDidDisappear: () => {
                  console.info("TextPickerDialog:onDidDisappear()")
                },
                onWillAppear: () => {
                  console.info("TextPickerDialog:onWillAppear()")
                },
                onWillDisappear: () => {
                  console.info("TextPickerDialog:onWillDisappear()")
                }
              })
            })
        }.width('100%')
      }.height('100%')
    }

  }
}
分享
微博
QQ
微信
回复
2天前
相关问题
如何修改WebuserAgent参数
360浏览 • 1回复 待解决
同意取消弹窗怎么实现?用哪个方法
4921浏览 • 1回复 待解决
HarmonyOS config可以设置headerRange吗?
154浏览 • 1回复 待解决
如何理解自定义弹窗gridCount参数
2451浏览 • 1回复 待解决