使用React和Mobx更改另一个数组中的数组中的元素后,重新渲染组件

时间:2018-10-29 21:34:39

标签: mobx mobx-react

我有一个复杂的表格,其中包含一系列问题。每个集合可以多次添加到表单中。示例是我从服务器获得的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传递到服务器来保存所有答案。但是我不能把答案寄给商店。也许有更好的做事方法?

This is how it looks when the data retrieved from the server

0 个答案:

没有答案