วิธีการแยกรายการด้วยแผนที่ไปยัง Wrapperclass
ฉันมีสตริงที่ฉันพยายามที่จะ deserialize เป็น wrapperclass / object แต่ได้รับข้อผิดพลาด:
Expected Map<String,String> but found [line:1, column:3]
Wrapperclass
global class Invocable_Obj_HandleInvoice {
@AuraEnabled global Id invoiceId;
@AuraEnabled global string invoiceNumber;
@AuraEnabled global decimal balanceAmount;
@AuraEnabled global decimal totalAmount;
@AuraEnabled global string customerName;
@AuraEnabled global string zuoraStatus;
@AuraEnabled global string handlingStatus;
@AuraEnabled global string selectedOption;
@AuraEnabled global Map<String, String> availableOptions;
}
สตริง
[
{
"availableOptions": [
{
"key": "e",
"value": "f"
},
{
"key": "g",
"value": "z"
}
],
"balanceAmount": -100,
"customerName": "Test",
"handlingStatus": "New",
"invoiceId": "a0S2o000023CSHoEAO",
"invoiceNumber": "INV-001",
"selectedOption": "A",
"totalAmount": -100,
"zuoraStatus": "Posted"
},
{
"availableOptions": [
{
"key": "a",
"value": "x"
},
{
"key": "b",
"value": "y"
},
{
"key": "c",
"value": "z"
}
],
"balanceAmount": -100,
"customerName": "Test",
"handlingStatus": "New",
"invoiceId": "a0S2o000023CSHoEAO",
"invoiceNumber": "INV-001",
"selectedOption": "y",
"totalAmount": -100,
"zuoraStatus": "Posted"
}
]
เอเพ็กซ์
system.debug((List<Invocable_Obj_HandleInvoice>) System.JSON.deserialize(invoices, List<Invocable_Obj_HandleInvoice>.class));
รายชื่อส่งไปยังส่วนประกอบฟ้าผ่า
List<Invocable_Obj_HandleInvoice> hiList = new List<Invocable_Obj_HandleInvoice>();
Invocable_Obj_HandleInvoice hi1 = new Invocable_Obj_HandleInvoice();
hi1.invoiceId = zi[0].id;
hi1.invoiceNumber = zi[0].Name;
hi1.balanceAmount = zi[0].Zuora__Balance2__c;
hi1.totalAmount = zi[0].Zuora__TotalAmount__c;
hi1.customerName = 'Test';
hi1.zuoraStatus = zi[0].Zuora__Status__c;
hi1.handlingStatus = zi[0].Handling_Status__c;
hi1.selectedOption = 'A';
hi1.availableOptions = new Map<String,string> {'e'=>'f', 'g'=> 'z'};
hiList.add(hi1);
return hiList;
ตัวควบคุมสายฟ้า
var act = cmp.get("c.updateInvoices");
var updatedInvoiceList = JSON.stringify(cmp.get('v.handleInvoices'));
act.setParams({ "invoices" : updatedInvoiceList});
$A.enqueueAction(act);
ส่วนประกอบ <ออร่า: แอตทริบิวต์ type = "รายการ" name = "handleInvoices" />
ตัวควบคุมสายฟ้า
doInit : function(cmp, event, helper) {
var action = cmp.get("c.testHandlInvoice");
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
cmp.set('v.handleInvoices', response.getReturnValue());
console.log(cmp.get('v.handleInvoices'));
}
});
$A.enqueueAction(action);
},
console.log
availableOptions: Array(3)
0: {key: "a", value: "x"}
1: {key: "b", value: "y"}
2: {key: "c", value: "z"}
length: 3
__proto__: Array(0)
balanceAmount: -100
customerName: "Test"
handlingStatus: "New"
invoiceId: "a0S2o000023CSHoEAO"
invoiceNumber: "INV-001"
selectedOption: "A"
totalAmount: -100
zuoraStatus: "Posted"
อัปเดต ***** สำหรับใครก็ตามที่ประสบปัญหานี้ฉันพบคำตอบด้านล่างนี้เพื่อแก้ไขปัญหาของแผนที่ แต่หลังจากที่ระบุว่าแผนที่ยังคงมีการเปลี่ยนแปลงดังนั้นฉันจึงยุติการรวมโซลูชันนี้โดยส่งผ่านวัตถุโดยตรง: วิธีส่งวัตถุจาก ตัวช่วย Lightning Component สำหรับวิธี Apex Controller
var act = cmp.get("c.updateInvoices");
var tempInvoiceList = cmp.get('v.handleInvoices');
tempInvoiceList = tempInvoiceList.slice(); // copy
tempInvoiceList = tempInvoiceList.map(function(invoice) { return Object.assign({}, invoice); }); // copy deeper
act.setParams({ "invoices" : tempInvoiceList});
tempInvoiceList = tempInvoiceList
.forEach(function(invoice) {
invoice.availableOptions = invoice.availableOptions
.reduce(function(prev, option) {
prev[option.key] = option.value;
return prev;
},
{})
}
);
$A.enqueueAction(act);
คำตอบ
@AuraEnabled global Map<String, String> availableOptions;
ควรจะเป็น:
@AuraEnabled global List<Map<String,String>> availableOptions;
หรือ:
@AuraEnabled global List<KeyValuePair> availableOptions;
อยู่ที่ไหนKeyValuePair
:
public class KeyValuePair {
@AuraEnabled public String key;
@AuraEnabled public String value;
}
ซึ่งใช้กันทั่วไปมากพอในโค้ดที่ฉันมีเป็นคลาสระดับบนสุดในองค์กรผู้พัฒนาของฉัน ฉันใช้มันค่อนข้างบ่อยสำหรับค่ารายการเลือกและอื่น ๆ
โดยทั่วไปแล้ว JSON ประเภทนี้ไม่ได้รับการสนับสนุน แต่ถ้าคุณต้องใช้ในลักษณะนั้นนี่คือรูปแบบที่ต้องการ ในการใช้เอเพ็กซ์ดั้งเดิมของคุณจำเป็นต้องจัดรูปแบบเป็น:
"availableOptions": { "e": "f", "g", "z" },
ซึ่งเป็นวิธีการจัดรูปแบบ JSON ในความหมายทั่วไปแม้ว่ารูปแบบก่อนหน้านี้จะยอมรับได้สำหรับกรณีต่างๆเช่นตัวเลือกรายการเลือกซึ่งมีค่าและป้ายกำกับ
ดูเหมือนว่าคุณต้องเปลี่ยน "availableOptions" ของคุณกลับไปเป็นแผนที่ที่เหมาะสมเพื่อให้ใช้งานได้อย่างถูกต้อง:
var act = cmp.get("c.updateInvoices");
var tempInvoiceList = cmp.get('v.handleInvoices');
tempInvoiceList = tempInvoiceList.slice(); // copy
tempInvoiceList = tempInvoiceList.map(function(invoice) { return Object.assign({}, invoice); }); // copy deeper
tempInvoiceList = tempInvoiceList
.forEach(function(invoice) {
invoice.availableOptions = invoice.availableOptions
.reduce(function(prev, option) {
prev[option.key] = option.value;
return prev;
},
{})
}
);
var updatedInvoiceList = JSON.stringify(tempInvoiceLIst);
act.setParams({ "invoices" : updatedInvoiceList});
$A.enqueueAction(act);
availableOptions
ใน JSON ของคุณไม่ใช่แผนที่ แต่เป็นรายการวัตถุ (ที่มีช่อง "คีย์" และ "ค่า")
ดังนั้นคลาส Wrapper ของคุณจึงต้องสะท้อนสิ่งนั้น แทนที่จะเป็นMap<String, String>
คุณต้องทำให้เป็น List ของคลาส / ประเภทอื่นที่สามารถเก็บข้อมูลเป้าหมายได้ ("คีย์" และ "ค่า")