我可能遇到了一个错误,或者对通用javascript语法有误解。使用ServiceNow UI Builder,我尝试刷新特定数据可视化组件的数据源。这需要我使用setState并发送整个JSON blob。
以下工作符合预期:
api.setState('intAssignedDonut', {
"header": "Interactions assigned to one of my groups",
"datasource": [{
"isDatabaseView": false,
"allowRealTime": true,
"sourceType": "table",
"label": {
"message": "Interaction"
},
"tableOrViewName": "interaction",
"filterQuery": "active=true^assignment_groupDYNAMICd6435e965f510100a9ad2572f2b47744",
"id": "intAssigned",
"elm": {}
}],
"metric": [{
"dataSource": "intAssigned",
"id": "intAssignedMetric",
"aggregateFunction": "COUNT",
"numberFormat": {
"customFormat": false
},
"axisId": "primary"
}],
"groupBy": [{
"maxNumberOfGroups": "ALL",
"numberOfGroupsBasedOn": "NO_OF_GROUP_BASED_ON_PER_METRIC",
"showOthers": false,
"groupBy": [{
"dataSource": "intAssigned",
"groupByField": "state",
"isRange": false,
"isPaBucket": false
}]
}]
});
然而,我只需要更改一些属性,而不是整个属性。所以我想我应该把这个东西克隆到一个临时对象中,改变我需要的东西,然后把克隆的对象传回来。
let clientState_intAssignedDonut = api.state.intAssignedDonut;
clientState_intAssignedDonut.header = 'Interactions assigned to one of my groups';
clientState_intAssignedDonut.datasource[0].filterQuery = 'active=true^assignment_groupDYNAMICd6435e965f510100a9ad2572f2b47744';
api.setState("intAssignedDonut", clientState_intAssignedDonut);
这似乎可以正确地更新头,但组件不会刷新数据源。即使我console.log api.state.intAssignedDonut,它看起来也与整个JSON blob完全相同。
编辑:我也尝试过使用排列运算符,但我不知道如何针对数据源[0]
api.setState("intAssignedDonut", {
...api.state.intAssignedDonut,
header: "Interactions assigned to one of my groups",
datasource[0].filterQuery: "active=true^assignment_groupDYNAMICd6435e965f510100a9ad2572f2b47744"
});
Javascript对象是passed by reference values
和react state is immutable
:
let clientState_intAssignedDonut = api.state.intAssignedDonut;
api.setState("intAssignedDonut", clientState_intAssignedDonut);
这是直接改变状态,如果下一个状态等于上一个状态,React将忽略您的更新,这是由Object.is
比较来确定的,以检查两个对象是否具有相同的值,请参阅文档
您的第二次尝试是使用排列运算符朝着正确的方向前进:
更新方法一:首先使用:JSON.parse(JSON.stringify(object))
复制嵌套对象,或者你可以在这个问题中找到其他方法:在JavaScript中深度克隆对象的最有效方法是什么?
let copied = JSON.parse(JSON.stringify(api.state.intAssignedDonut)); // copy a nested object
copied.header = "Interactions assigned to one of my groups";
copied.datasource[0].filterQuery = "active=true^assignment_groupDYNAMICd6435e965f510100a9ad2572f2b47744";
setState("intAssignedDonut",copied);
更新方法二:
setState("intAssignedDonut",{
...api.state.intAssignedDonut,
header: "Interactions assigned to one of my groups",
datasource: [{ ...state.datasource[0], filterQuery: "active=true^assignment_groupDYNAMICd6435e965f510100a9ad2572f2b47744" }]
});
查看沙箱