我有一个复杂的表格,其中包含一系列问题。每个集合可以多次添加到表单中。示例是我从服务器获得的JSON。
{
"Form": {
"Level1Id": 2,
"DisplayName": "Liabilities",
"UniqueCode": "$L1_TL",
"Level2s": [
{
"Id": 3,
"UniqueCode": "$L2_TL_CR",
"DisplayName": "Credits",
"MaxOccurs": null,
"Level2Groups": [
{
"GroupId": "3",
"QuestionsWithAnswers": [
{
"DisplayName": "Remain",
"InputType": 4,
"UniqueCode": "$L3_CR_RMN",
"GroupId": "3",
"AnswerId": 3,
"Answer": "10000",
"Id": 5
},
{
"DisplayName": "Monthly Payment",
"InputType": 4,
"UniqueCode": "$L3_CR_PMN",
"GroupId": "3",
"AnswerId": 4,
"Answer": "1000",
"Id": 6
},
{
"DisplayName": "Last Payment Date",
"InputType": 10,
"UniqueCode": "$L3_CR_ED",
"GroupId": "3",
"AnswerId": 5,
"Answer": "2020-10-28 11:21:18.926961",
"Id": 7
}
]
}
]
}
]
},
"Total": 6
}
Level2s是包含问题组(Level2Groups)的数组。每个组都有QuestionsWithAnswers,其中每个元素代表其中包含值(答案)的某些输入。我需要做的是,如果Level2s的元素具有MaxOccurs> 1或为null,以将特定Group2s元素的组添加到Level2Groups中。
我使用Mobx作为存储所有表单信息的商店。我什至可以在需要的地方添加一个元素,然后调用rerender,但是视图上没有任何变化。
我在商店回答问题也很困难。
这是react的代码。 (不是所有的代码,只是重要的部分)
Mobx商店:
@observable
form = {
DisplayName: "L1Name",
}
@observable
lvl2s = [];
//here I get JSON from server
@action
setData(data) {
debugger;
this.form = data.Form;
this.lvl2s = data.Form.Level2s;
super.setData();
}
@action
addCategoryToLevel(levelId) {
debugger;
var copy = toJS(this.lvl2s);
const filteredArray = this.lvl2s.filter(item => item.Id === levelId);
const QAs = filteredArray[0].Level2Groups[0].QuestionsWithAnswers;
const copyQAs = [];
const grId = uuid();
for (let i = 0; i < QAs.length; i++) {
copyQAs.push(
{
DisplayName: QAs[i].DisplayName,
UniqueCode: QAs[i].UniqueCode,
InputType: QAs[i].InputType,
Id: QAs[i].Id,
Answer: null,
AnswerId: 0,
MaxOccurs: QAs[i].MaxOccurs,
})
}
var newQQ = filteredArray[0].Level2Groups.concat({ GroupId: grId, QuestionsWithAnswers: copyQAs });
filteredArray[0].Level2Groups = newQQ;
var newAll = [];
this.lvl2s.map(item => {
if (item.Id !== levelId)
newAll.push(toJS(item));
else
newAll.push(filteredArray[0]);
});
debugger;
this.lvl2s.replace(newAll);//from Mobx docs
// I replace everything with new values, where the desired things are added
}
这是魔术开始的基本组成部分:
render() {
const { form, lvl2s } = this.formStore;
return (
<WizardForm form={form} lvl2s={lvl2s}/>
);}
这是WizardFrom组件:
@observer
export class WizardForm extends React.Component {
constructor(props) {
super(props);
this.formStore = getComp('QuestionFormStore');
this.state = {
form: props.form,
}
}
render() {
debugger;
const { form } = this.state;
const { lvl2s } = this.formStore;
//lvl2s is the array that was changed. I call toJS to check what is inside
//after I add a new group the structure is correct, but the new elements won't show up
const ss = toJS(lvl2s);
return (
<div>
<h2>{form.DisplayName}</h2>
{lvl2s.map((level2, i) => {
debugger;
return (<div>
<h3 >{level2.DisplayName}</h3>
<WizardStepCategory groups={level2.Level2Groups} maxOccurs={level2.MaxOccurs} levelId={level2.Id} />
</div>);
})}
</div>
);
}
}
这是WizardStepCategory组件:
@observer
export class WizardStepCategory extends React.Component {
constructor(props) {
super(props);
this.state = {
groups: props.groups,
maxOccurs: props.maxOccurs,
levelId: props.levelId,
}
this.formStore = getComp('QuestionFormStore');
}
@action
handleClick(event) {
debugger;
this.formStore.addCategoryToLevel(this.state.levelId);
//here I add a new set of questions with answer
}
render() {
debugger;
const { groups, maxOccurs } = this.state;
return (
<div>
{groups.map((group, i) => {
debugger;
const canAdd = (maxOccurs == null) | ((maxOccurs > 1) & groups.length < maxOccurs);
return <div >
<WizardQuestion questionsWithAnswers={group.QuestionsWithAnswers} groupId={group.GroupId} />
{canAdd && <button onClick={(event) => this.handleClick(group, event)}>ADD</button>}
</div>
})}
</div>
);
}
}
最后是WizardQuestion组件。
@observer
export class WizardQuestion extends React.Component {
constructor(props) {
super(props);
this.state = {
questionsWithAnswers: props.questionsWithAnswers,
groupId: props.groupId,
}
}
handleValueChange(value, question) {
debugger;
question.Answer = value.floatValue;
}
render() {
debugger;
const { questionsWithAnswers, maxOccurs, groupId } = this.state;
return (
<div>
{questionsWithAnswers.map((question, i) => {
let inputEl;
if (question.InputType === 4)
inputEl = <DecimalInput answer={question.Answer} question={question} handleValueChange={this.handleValueChange} />; }
return <div key={i}>
{question.DisplayName}
<br />
{inputEl}
</div>
})}
</div>
);
}
}
这是它的外观图片。当您按下ADD时,必须出现3个新的输入元素。当我更改表单的当前步骤时,我想通过将FormStore传递到服务器来保存所有答案。但是我不能把答案寄给商店。也许有更好的做事方法?