wrapperclass에 매핑을 사용하여 목록을 역 직렬화하는 방법

Aug 18 2020

랩퍼 클래스 / 객체로 역 직렬화하려는 문자열이 있습니다. 그러나 오류가 발생합니다.

Expected Map<String,String> but found [line:1, column:3]

래퍼 클래스

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); 

구성 요소 <aura : attribute type = "List"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"

UPDATE *****이 문제에 부딪히는 사람을 위해 아래 답변이지도 문제를 해결한다는 것을 알아 냈지만 stringify 후에도지도가 여전히 변경되었으므로이 솔루션을 결합하여 객체를 직접 전달하는 방법을 끝냈습니다 . Apex 컨트롤러 메서드에 대한 Lightning 구성 요소 도우미

  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); 

답변

3 sfdcfox Aug 18 2020 at 19:40
@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은 일반적으로 권장되지 않지만 그런 방식으로 사용해야하는 경우 선호되는 형식입니다. 원본 Apex를 사용하려면 다음과 같은 형식이어야합니다.

"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); 
DerekF Aug 18 2020 at 19:41

availableOptions JSON에서 맵이 아니라 개체 목록입니다 (필드 "키"및 "값"포함).

따라서 래퍼 클래스는이를 반영해야합니다. 대신 Map<String, String>대상 데이터 ( "키"및 "값")를 보유 할 수있는 다른 클래스 / 유형의 목록으로 만들어야합니다.