pro-components icon indicating copy to clipboard operation
pro-components copied to clipboard

🧐[问题] ProFormList 能否支持 tranform?

Open Robotxm opened this issue 3 years ago • 5 comments
trafficstars

提问前先看看:

https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md

🧐 问题描述

有一个比较小众和奇怪的需求,后端会返回一个 URL 字符串,例如 app://link?target=123&title=test 这样,前端想要通过 ProFormList 来方便地进行修改。目前看可以通过在 initialValue 处理来把字符串解析成对象,但是好像没有 transform 来把对象重新拼接成字符串?

💻 示例代码

🚑 其他信息

Robotxm avatar Sep 10 '22 09:09 Robotxm

不支持诶,ProFormList 只是个数据聚合拼接工具,不过支持下好像会更好用

chenshuai2144 avatar Dec 26 '22 11:12 chenshuai2144

不支持诶,ProFormList 只是个数据聚合拼接工具,不过支持下好像会更好用

目前遇到在 ProFormList 里面的表单元素需要去做 tranform 有没有什么办法可以先解决,我也有提了issue了

cjm61177 avatar Dec 28 '22 10:12 cjm61177

TAutomatically replying with ChatGPT can be attempted, but it cannot be guaranteed to be completely accurate and may not fully address all issues. Please feel free to reply if you have any further questions or concerns. 此回复基于 ChatGPT 自动生成,可以尝试下方案,官方员会在一定时间后继续继续处理。

还是参照 initialValue 的方案,将 URL 字符串解析成对象后,可以通过 onValuesChange 在表单值变化时重新拼接成字符串并更新到表单中。以下是一个简单的示例代码:

import React from 'react';
import { Form, Input, Button, message } from 'antd';
const { Item: FormItem } = Form;

const initialUrl = 'app://link?target=123&title=test';

function parseUrl(url) {
  const [path, query] = url.split('?');
  const queryObj = {};
  if (query) {
    query.split('&').forEach((param) => {
      const [key, value] = param.split('=');
      queryObj[key] = value;
    });
  }
  return {
    path,
    queryObj
  };
}

function toUrlString({ path, queryObj }) {
  const queryArr = Object.entries(queryObj).map(([key, value]) => `${key}=${value}`);
  return `${path}?${queryArr.join('&')}`;
}

export default function Example() {
  const [form] = Form.useForm();

  function handleValuesChange(changedValues, allValues) {
    // 重新拼接 URL 字符串
    const urlObj = {
      path: parseUrl(initialUrl).path, // 维持 path 不变
      queryObj: allValues
    };
    const fullUrl = toUrlString(urlObj);
    form.setFieldsValue({
      url: fullUrl // 更新到表单中
    });
  }

  return (
    <Form form={form} onValuesChange={handleValuesChange} initialValues={parseUrl(initialUrl).queryObj}>
      <FormItem
        name="target"
        label="Target"
        rules={[
          {
            required: true,
            message: 'Target is required'
          }
        ]}
      >
        <Input />
      </FormItem>
      <FormItem
        name="title"
        label="Title"
        rules={[
          {
            required: true,
            message: 'Title is required'
          }
        ]}
      >
        <Input />
      </FormItem>
      <FormItem>
        <Button type="primary" onClick={() => message.success(`URL: ${form.getFieldValue('url')}`)}>
          Submit
        </Button>
      </FormItem>
      <FormItem label="URL">
        <Input disabled={true} value={initialUrl} />
      </FormItem>
    </Form>
  );
}

这里用到了两个辅助函数 parseUrltoUrlString 来解析 URL 字符串和拼接 URL 字符串。其中 parseUrl 把字符串解析成对应的对象,形如 { path: 'app://link', queryObj: { target: '123', title: 'test' } }toUrlString 则把对象拼接成 URL 字符串的形式。

handleValuesChange 函数会在表单值发生变化时被调用,重新拼接 URL 对象并更新到表单中。这里用到了 form.setFieldsValue 函数来设置表单某字段的值。

在表单渲染时,用 initialValues 把解析后的 queryObj 作为表单组件的初始值,然后在一个不可编辑的表单项中显示初始的 URL 字符串 initialUrl 作为比对。

你需要根据自己的需求来修改 parseUrltoUrlString 函数的实现,比如更复杂的 URL 字符串解析规则。关于 onValuesChange 和相关表单组件 API,可以参考 antd 官方文档:https://ant.design/components/form-cn/

chenshuai2144 avatar Mar 06 '23 10:03 chenshuai2144

onValuesChange 去修改 是不是太频繁了 支持下transform会更好

zwmmm avatar Jul 11 '23 03:07 zwmmm

希望能支持一下,这边使用场景会是在 ProForm 里的个别栏位(包含 ProFormList )做好相关的 transform 转换,并在 onFinish 内透过指定型别使后续逻辑可直接取用整包正确转换后的资料 onFinish={(formData) => handleFinish(formData as ITransformFormValuesType)}

如果按照上面的范例,那整个表单只有 ProFormList 的资料要再另外地方( onValuesChange )做转换,并且得为他提供个 formRef 才能处理;整个转换逻辑就这样产生了特例,如果有支援的话就可以与其他 栏位一致都在 ProFormFields 内做转换。

比较直觉的说法是所有可透过 name 属性抓取并接手操作表单值的组件,都具有 transform 属性,方便针对该栏位值做转换~

leadingtw273 avatar Feb 26 '24 07:02 leadingtw273

支持了 2.7 之后可以直接使用

chenshuai2144 avatar Apr 19 '24 06:04 chenshuai2144