有没有办法将多个(和不同的)参数从 Lightning Web Components (LWC) 中的 JS 传递到 Apex Controller class?

Is there a way to pass multiple (and different) parameters to an Apex Controller class from JS in Lightning Web Components (LWC)?

我目前遇到了一个问题,希望这里有人能帮助我。我当然也希望这是问它的正确地方。

我正在尝试在触发事件时创建一个自定义发票记录及其对应的发票行记录。我已经有了一些逻辑来收集 JS 中选定行的 ID。

我已经能够创建发票记录(使用 LDS)和发票行记录(使用 Apex),但似乎无法为发票行记录传递发票 ID。我知道我能够创建记录,因为当我用硬编码的发票 ID 测试它时它可以工作。

是否可以将 List 和 String 的多个参数传递给 LWC 中的 Apex 方法?

如有任何帮助,我将不胜感激。提前致谢!

JS

    selectedRowsEvent(event) {

    ...some codes here...

    this.selectedRecords = Array.from(conIds);
    }


    handleSave() {

         **invId;**

         ...some codes here...

        createRecord(recordInput)
        .then(invoice => {
            **this.invId = invoice.Id;**  
            **createInvLines({ lstConIds : this.selectedRecords, invoiceId : this.invId})**
        }).catch(error => {

          ...some codes here...

          });
    }

控制器

@AuraEnabled
    public static void createInvLines(list<Id> lstConIds, string invoiceId){
        if(lstConIds.size() > 0){
            List<OpportunityLine__c> oppLst = new List<OpportunityLine__c>([SELECT Id, Description__c FROM OpportunityLine__c WHERE Id = :lstConIds]);
            try {
                List<InvoiceLine__c> lstInvLinesToInsert = new List<InvoiceLine__c>();
                for(OpportunityLine__c idCon : oppLst) {
                    lstInvLinesToInsert.add(new InvoiceLine__c(**InvoiceId__c = invoiceId**, Description__c = idCon.Description__c));
                }
                if(!lstInvLinesToInsert.isEmpty()) {
                    insert lstInvLinesToInsert;
                }
            }
            catch(Exception ex) {
                throw new AuraHandledException(ex.getMessage());
            }
        }
    }  

问题是插入是异步的,而您是同步触发它们的。所以,这意味着您正试图在父记录完成之前插入这些行。

// CREATE THE INVOICE RECORD
    createRecord(recordInput)
        .then(invoice => {
                **this.invId = invoice.Id;**
                // Call the next function here

                   // CREATE THE INVOICE LINE RECORDS
                **createInvLines({ lstConIds : this.selectedRecords, invoiceId : this.invId})**
                 .then(result => {
                   ...some codes here...
                  })
                 .catch(error => {
                   ...some codes here...

                 }); 
              );
            }

是的,您可以将复杂参数传递给标记为 @AuraEnabled 的方法。在客户端,它将是一个具有正确字段名称的 JSON 对象,就像您已经拥有 { lstConIds : this.selectedRecords, invoiceId : this.invId} 一样。在 Apex 端,它可以是一个具有多个参数或只有 1 个参数的函数(一些辅助包装器 class,同样具有正确的字段名称)。 Salesforce 将 "unpack" 为您 JSON 并在调用您的代码之前将其放入正确的字段中。

您喜欢哪个更干净。我倾向于使用包装纸。如果你有一个可重用的类似服务的功能,并且你想稍后添加一些可选参数 - 你只需将新字段放入包装器 class 中即可完成工作。向其他顶点代码中使用的函数添加新参数可能不那么容易,有点混乱。

(在您的情况下,我肯定会尝试将发票和订单项创建为 1 个调用,因此如果有任何失败 - 正常的事务回滚将帮助您。如果其中一个项目失败 - 您不想被留下只有发票抬头,对吗?)

你见过https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.apex吗?这是一堵文字墙,但它提到了有趣的例子,在那里搜索 "apexImperativeMethodWithParams"。

在此处查看 JS 文件:https://github.com/trailheadapps/lwc-recipes/tree/master/force-app/main/default/lwc/apexImperativeMethodWithComplexParams 看看它如何调用

ApexTypesController {
    @AuraEnabled(cacheable=true)
    public static String checkApexTypes(CustomWrapper wrapper) {
...

其中CustomWrapper

public with sharing class CustomWrapper {
    class InnerWrapper {
        @AuraEnabled
        public Integer someInnerInteger { get; set; }
        @AuraEnabled
        public String someInnerString { get; set; }
    }

    @AuraEnabled
    public Integer someInteger { get; set; }
    @AuraEnabled
    public String someString { get; set; }
    @AuraEnabled
    public List<InnerWrapper> someList { get; set; }
}