DevExtreme-Reactive中CustomTreeData组件的GraphQL数据转换

此处以树的形式显示数据,并具有编辑不同字段,删除/添加行等的功能。 在寻找合适的组件的过程中(我想在material-ui下找到并做出反应),我开始尝试devextreme-active 。 但是,Newans发现devextreme-reactive希望将树的数据作为对象的平面数组,每个对象都包含“父”对象的parent_id。 GraphQL服务器以嵌套对象和对象数组的形式为我提供了一棵树。 我必须做另一件事-也许有人会派上用场。 也许有人会说我对此案并不感到困惑,而这一切都容易完成。

因此,响应GraphQL查询(有测试,每个都有问题,每个调查都有几个答案选项,我们希望一次获得所有信息):

query TestQuery { tests { id title questions { id title answers { id title } } } } 

我们从服务器收到以下形式的响应:

扰流板方向
 { "data": { "tests": [ { "id": "test_1", "title": "Test 1", "questions": [ { "id": "question_1", "title": "Question 1 (for t1)", "answers": [ { "id": "answer_1", "title": "Answer 1 (for q1)" }, { "id": "answer_2", "title": "Answer 2 (for q1)" } ] }, { "id": "question_2", "title": "Question 2 (for t1)", "answers": [ { "id": "answer_1_2", "title": "Answer 1 (for q2)" } ] } ] }, { "id": "test_2", "title": "Test 2", "questions": [ { "id": "question_1_2", "title": "Question 1 (for t2)", "answers": [] } ] }, { "id": "test_3", "title": "Test 3", "questions": [] } ] } } 


要规范化,请使用normalizr

在该方案的描述中,通过processStrategy,我们为孩子添加了pid属性以及与父母的链接。 顺便说一句,在新的规范中,描述电路的方式已经改变,因此,带有assignEntity,ArrayOf,define(很多)的示例几乎是不相关的。

 const answerSchema = new schema.Entity('answers',{}, { processStrategy: (entity, parent, key) => { return { ...entity, pid: parent.id} } } ) const questionSchema = new schema.Entity('questions',{ answers:[answerSchema]}, { processStrategy: (entity, parent, key) => { return { ...entity, pid: parent.id} } }, ) const testSchema = new schema.Entity('tests',{questions:[questionSchema]}, { processStrategy: (entity, parent, key) => { return { ...entity, pid: 0 } } } ) const nRes = normalize(result.data, {tests: [testSchema]}) 

我们得到这个:

扰流板方向
 { "entities": { "answers": { "answer_1": { "id": "answer_1", "title": "Answer 1 (for q1)", "__typename": "Answer", "pid": "question_1" }, "answer_2": { "id": "answer_2", "title": "Answer 2 (for q1)", "__typename": "Answer", "pid": "question_1" }, "answer_1_2": { "id": "answer_1_2", "title": "Answer 1 (for q2)", "__typename": "Answer", "pid": "question_2" } }, "questions": { "question_1": { "id": "question_1", "title": "Question 1 (for t1)", "answers": [ "answer_1", "answer_2" ], "__typename": "Question", "pid": "test_1" }, "question_2": { "id": "question_2", "title": "Question 2 (for t1)", "answers": [ "answer_1_2" ], "__typename": "Question", "pid": "test_1" }, "question_1_2": { "id": "question_1_2", "title": "Question 1 (for t2)", "answers": [ ], "__typename": "Question", "pid": "test_2" } }, "tests": { "test_1": { "id": "test_1", "title": "Test 1", "questions": [ "question_1", "question_2" ], "__typename": "Test", "pid": 0 }, "test_2": { "id": "test_2", "title": "Test 2", "questions": [ "question_1_2" ], "__typename": "Test", "pid": 0 }, "test_3": { "id": "test_3", "title": "Test 3", "questions": [ ], "__typename": "Test", "pid": 0 } } }, "result": { "tests": [ "test_1", "test_2", "test_3" ] } } 


从这里我们只对.entities感兴趣

 const normalized = { entities: nRes.entities } 

顺便说一句,在进入normalizr的过程中,阅读了一些问题之后,我发现我并不是唯一一个尝试不完全按其预期目的使用它的人(可能只是因为它几乎是唯一这样的工具)。 许多人渴望获得各种各样的功能,以便以最可定制的格式获得结果。 但是作者很fl。

鉴于上述情况,必须使用flat来对normalizr的结果进行展 (我们将其递归扩展到所需的嵌套级别):

 const flattened = flatten({ entities: nRes.entities }, { maxDepth: 3 }) 

我们得到以下内容:

扰流板方向
 { "entities.answers.answer_1": { "id": "answer_1", "title": "Answer 1 (for q1)", "__typename": "Answer", "pid": "question_1" }, "entities.answers.answer_2": { "id": "answer_2", "title": "Answer 2 (for q1)", "__typename": "Answer", "pid": "question_1" }, "entities.answers.answer_1_2": { "id": "answer_1_2", "title": "Answer 1 (for q2)", "__typename": "Answer", "pid": "question_2" }, "entities.questions.question_1": { "id": "question_1", "title": "Question 1 (for t1)", "answers": [ "answer_1", "answer_2" ], "__typename": "Question", "pid": "test_1" }, "entities.questions.question_2": { "id": "question_2", "title": "Question 2 (for t1)", "answers": [ "answer_1_2" ], "__typename": "Question", "pid": "test_1" }, "entities.questions.question_1_2": { "id": "question_1_2", "title": "Question 1 (for t2)", "answers": [ ], "__typename": "Question", "pid": "test_2" }, "entities.tests.test_1": { "id": "test_1", "title": "Test 1", "questions": [ "question_1", "question_2" ], "__typename": "Test", "pid": 0 }, "entities.tests.test_2": { "id": "test_2", "title": "Test 2", "questions": [ "question_1_2" ], "__typename": "Test", "pid": 0 }, "entities.tests.test_3": { "id": "test_3", "title": "Test 3", "questions": [ ], "__typename": "Test", "pid": 0 } } 


摆脱指数:

 Object.keys(flattened).forEach( (key)=> rows.push(flattened[key]) ) 

我们得到:

扰流板方向
 [ { "id": "answer_1", "title": "Answer 1 (for q1)", "__typename": "Answer", "pid": "question_1" }, { "id": "answer_2", "title": "Answer 2 (for q1)", "__typename": "Answer", "pid": "question_1" }, { "id": "answer_1_2", "title": "Answer 1 (for q2)", "__typename": "Answer", "pid": "question_2" }, { "id": "question_1", "title": "Question 1 (for t1)", "answers": [ "answer_1", "answer_2" ], "__typename": "Question", "pid": "test_1" }, { "id": "question_2", "title": "Question 2 (for t1)", "answers": [ "answer_1_2" ], "__typename": "Question", "pid": "test_1" }, { "id": "question_1_2", "title": "Question 1 (for t2)", "answers": [ ], "__typename": "Question", "pid": "test_2" }, { "id": "test_1", "title": "Test 1", "questions": [ "question_1", "question_2" ], "__typename": "Test", "pid": 0 }, { "id": "test_2", "title": "Test 2", "questions": [ "question_1_2" ], "__typename": "Test", "pid": 0 }, { "id": "test_3", "title": "Test 3", "questions": [ ], "__typename": "Test", "pid": 0 } ] 


可以清理剩余的问题阵列,此处剩余的答案,但是这些都是琐碎的事情-它们不会影响显示。 并且需要__typename,以便稍后在编辑时我们了解我们要处理的内容。

在组件中,如示例中所示处理结果:

 ... <CustomTreeData getChildRows={getChildRows} /> ... const getChildRows = (currentRow, rootRows) => { const childRows = rootRows.filter(r => r.pid === (currentRow ? currentRow.id : 0)); const res = childRows.length ? childRows : null return res } ... 

似乎上述所有方法的替代方法可能是直接读取GraphQL存储区的内容(在Apollo客户端中)-所有内容也都应该放在那儿。 但是,老实说,我没有找到如何以标准方式完成此操作,而且我不太确定存储数据的格式在新版本中不会改变。

Source: https://habr.com/ru/post/zh-CN416111/


All Articles