---
order: 9
zh-CN:
	title: 从 Model 构建表单
	addHobby: 添加兴趣爱好
	delHobby: 删除该爱好
	hobby: 兴趣爱好
	hobbyValidation: 请填写兴趣爱好
	addMember: 添加一个成员
	addTwoMembers: 添加两个成员
	delMember: 删除该成员
	member: 成员
	name: 名字
	sex: 性别
	nameValidationError: 请填写成员名字
	sexValidationError: 请选择性别
	male: 男
	female: 女
	totalNumber: 总人数
	totalNumberError: 请填写总人数
	submit: 获取表单值
	submitValue: 获取表单提交值
	setArray: 设置 FieldArray 值
en-US:
	title: build form from model
	addHobby: Add hobby
	delHobby: Delete hobby
	hobby: Hobby
	hobbyValidation: Please enter the hobby.
	addMember: Add one member
	addTwoMembers: Add two members
	delMember: Delete member
	member: Member
	name: Name
	sex: Sex
	nameValidationError: Please enter the name of member.
	sexValidationError: Please select the sex of member.
	male: male
	female: female
	totalNumber: Total number
	totalNumberError: Please enter the total number of the family.
	submit: Get Form Value
	submitValue: Get Submit Value
	setArray: Set FieldArray
---

```jsx
import {
	Form,
	Icon,
	Pop,
	Notify,
	FieldModel,
	FieldSetModel,
	FieldSet,
	Validators,
	FormStrategy,
	FormNumberInputField,
} from 'zent';

const { form, field, array, set } = Form;

function hobbyFactory(defaultValue = '') {
	return field(defaultValue);
}

function Hobbies({ model: propsModel }) {
	const model = Form.useFieldArray(propsModel);
	const addHobby = useCallback(() => {
		model.push('');
	}, []);
	return (
		<>
			<Button onClick={addHobby} className="add-btn">
				{i18n.addHobby}
			</Button>
			<ul>
				{model.children.map((child, index) => (
					<li key={child.id} className="hobby">
						<FormInputField
							model={child}
							label={`{i18n.hobby}${index + 1}：`}
							props={{
								width: 120,
							}}
						/>
						<span className="del-btn" onClick={() => model.splice(index, 1)}>
							{i18n.delHobby}
						</span>
					</li>
				))}
			</ul>
		</>
	);
}

function MemberInfo({ remove, index, model }) {
	const { name, sex, hobbies } = model.children;
	const onRemoveClick = useCallback(() => {
		remove(index);
	}, [index, remove]);
	return (
		<FieldSet model={model}>
			<li className="members">
				<div className="member-title">
					<span>
						{i18n.member}
						{index + 1}
					</span>
					<Pop centerArrow trigger="hover" content="{i18n.delMember}">
						<Icon
							className="del-btn"
							type="close-circle"
							onClick={onRemoveClick}
						/>
					</Pop>
				</div>
				<FormInputField
					model={name}
					label="{i18n.name}："
					required
				/>
				<FormRadioGroupField model={sex} label="{i18n.sex}：" required>
					<Radio value="1">{i18n.male}</Radio>
					<Radio value="2">{i18n.female}</Radio>
				</FormRadioGroupField>
				<Hobbies model={hobbies} />
			</li>
		</FieldSet>
	);
}

function Members({ model: propsModel }) {
	const model = Form.useFieldArray(propsModel);
	const addOne = useCallback(() => {
		model.push({});
	}, [model]);
	const addTwo = useCallback(() => {
		model.push({}, {});
	}, [model]);
	const remove = useCallback(
		index => {
			model.splice(index, 1);
		},
		[model]
	);
	return (
		<>
			{model.children.length < 3 && (
				<Button onClick={addOne} className="add-btn">
					{i18n.addMember}
				</Button>
			)}
			{model.children.length < 2 && (
				<Button onClick={addTwo} className="add-btn">
					{i18n.addTwoMembers}
				</Button>
			)}
			<ul>
				{model.children.map((child, index) => (
					<MemberInfo key={child.id} model={child} index={index} remove={remove} />
				))}
			</ul>
		</>
	);
}

const formBuilder = form({
	number: field('').validators(Validators.required('{i18n.totalNumberError}')),
	members: array(
		set({
			name: field('')
				.validators(Validators.required('{i18n.nameValidationError}'))
				.normalizeBeforeSubmit(name => name.toUpperCase()),
			sex: field('1').validators(
				Validators.required('{i18n.sexValidationError}')
			),
			hobbies: array(
				field('').validators(Validators.required('{i18n.hobbyValidation}'))
			).defaultValue([]),
		})
	),
});

function App() {
	const form = Form.useForm(formBuilder);
	const { number, members } = form.model.children;
	const setArray = useCallback(() => {
		form.patchValue({
			number: 42,
			members: [
				{
					name: 'john',
					sex: '1',
					hobbies: ['H1'],
				},
			],
		});
	}, [form]);

	const getFormValue = useCallback(() => {
		console.log(form.getValue());
	}, [form]);

	const getSubmitValue = useCallback(() => {
		console.log(form.getSubmitValue());
	}, [form]);

	return (
		<Form className="demo-form" layout="horizontal" form={form}>
			<FormNumberInputField
				model={number}
				label="{i18n.totalNumber}："
				required
			/>
			<Members model={members} />
			<div style={{ marginTop: 16 }}>
				<Button type="primary" htmlType="submit" onClick={getFormValue}>
					{i18n.submit}
				</Button>
				<Button type="primary" htmlType="submit" onClick={getSubmitValue}>
					{i18n.submitValue}
				</Button>
				<Button onClick={setArray}>{i18n.setArray}</Button>
			</div>
		</Form>
	);
}

ReactDOM.render(<App />, mountNode);
```
