Lightning-覆盖标准按钮(3)

当从Visualforce世界转移到Lightning组件时,开发人员面临的一个重大变化是如何与服务器通信。直到Summer ’17发布,这意味着创建一个Apex类来做任何事情,甚至是在Visualforce中“自动”处理的简单的CRUD交互。随着夏季’17发布和闪电数据服务的引入,这一切都改变了。因此,对于我们的组件,我们使用Lightning Data Service创建新的属性记录 – 无需编写Apex!

添加force:recordData

  1. 在开发人员控制台的PropertyDialog组件中,在刚添加的aura:attribute和c:PickListValues之间添加以下内容:
    <aura:attribute name="propertyRecord" type="Property__c" />
    <force:recordData aura:id="forceRecord"
                    recordId="{!v.recordId}"
                    targetFields="{!v.propertyRecord}"
                    fields="Id,Name,Beds__c,Baths__c,Price__c,Status__c"
                    mode="EDIT" />
    

    Lightning Data Service使用名为force:recordData的对象在记录上执行CRUD交互。 force有几个其他的属性:recordData,但是为了我们的目的,我们只需要recordId,targetRecord,fields和mode。

    当值被分配给recordId属性时,在场景后面,Lightning Data Service将检索整个记录或请求的字段。结果字段存储在由targetFields属性定义的属性中;在这种情况下,propertyRecord。最后,mode属性定义了force:recordData的这个实例是处于VIEW模式还是EDIT模式。显然,由于我们正在创建一个记录,它需要处于编辑模式。

初始化新记录

  1. 在force之后的新行添加以下内容:recordData标记:
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    
  2. 单击侧面导航中的“控制器”以将控制器添加到组件。
  3. 将默认函数myAction重命名为doInit,并将以下内容添加到函数中:
    component.find("forceRecord").getNewRecord(
            "Property__c",
            null,
            false,
            $A.getCallback(function() {
                var rec = component.get("v.propertyRecord");
                var error = component.get("v.recordError");
                if (error || (rec === null)) {
                    console.log("Error initializing record template: " + error);
                    return;
                }
            })
        );
    
    强制的getNewRecord:recordData有四个参数。第一个参数Property__c定义要创建记录的sObject的实体API名称。下一个参数是recordTypeId。我们将其设置为空,它只是说根据用户的配置文件使用默认的记录类型。第三个参数决定是否从客户端缓存加载记录模板。最后,回调检查是否有错误或者propertyRecord属性是否未被填充。

保存新记录

  1. 在PropertyDialogController中添加一个名为saveRecord的新函数,并传递组件,事件,帮助器作为参数:
    saveRecord : function(component, event, helper) {
    }
    
    不要忘记逗号分隔功能!
  2. 将以下内容添加到新功能中:
    var propBeds = parseInt(component.find('propBeds').get("v.value"), 10);
    var propBaths = parseInt(component.find('propBaths').get("v.value"), 10);
    var propPrice = parseInt(component.find('propPrice').get("v.value"), 10);
    
    component.set("v.propertyRecord.Name", component.find('propName').get("v.value"));    
    component.set("v.propertyRecord.Beds__c", propBeds);
    component.set("v.propertyRecord.Baths__c", propBaths);
    component.set("v.propertyRecord.Price__c", propPrice);
    component.set("v.propertyRecord.Status__c", component.find('propStatus').get("v.value"));
    
    var tempRec = component.find("forceRecord");
    tempRec.saveRecord($A.getCallback(function(result) {
        console.log(result.state);
        var resultsToast = $A.get("e.force:showToast");
        if (result.state === "SUCCESS") {
            resultsToast.setParams({
                "title": "Saved",
                "message": "The record was saved."
            });
            resultsToast.fire();                
        } else if (result.state === "ERROR") {
            console.log('Error: ' + JSON.stringify(result.error));
            resultsToast.setParams({
                "title": "Error",
                "message": "There was an error saving the record: " + JSON.stringify(result.error)
            });
            resultsToast.fire();
        } else {
            console.log('Unknown problem, state: ' + result.state + ', error: ' + JSON.stringify(result.error));
        }
    }));
    

    当我们保存记录时,我们确保字段类型的值是正确的。 Beds__c,Baths__c和Price__c都被设置为Property_c对象中的整数。因此,当我们从输入中获取值时,我们使用parseInt JavaScript方法将其从一个字符串转换为一个整数。一旦转换,我们更新propertyRecord属性中的值以及来自其他表单字段的值。

    接下来,我们使用tempRec的变量赋值来调用saveRecord的force:recordData方法,以将记录的新值保存回Salesforce。哦,我们是否提到过那是?真的,tempRec.saveRecord(),我们完成了!

    当然,在saveRecord方法的回调中还有更多。确保记录成功保存后,我们吐出一杯祝酒词,让用户知道保存是否奏效。

  3. 保存PropertyDialogController.js并切换回PropertyDialog组件。
  4. onclick="{!c.saveRecord}" 添加到提交对话框的lightning:button   (标签为“submit”的按钮).
  5. 保存文件。

导航到保存后的新记录

记录保存后,我们不希望对话框坐在那里。因此,我们可以选择:导航到“属性”列表或新创建的记录。让我们做一个行政决定,并导航到新创建的记录。

  1. 在开发人员控制台中,单击侧面导航栏中的“助手”以将助手文件添加到组件。

    当您最初开始构建Lightning组件时,将所有JavaScript函数放在控制器文件中感觉很自然。但是,在控制器文件中,不能从另一个函数调用一个函数。所以,在我们的例子中,如果我们构建了一个导航到记录的函数,我们不能从saveRecord函数中调用它。这意味着我们必须将整个功能写入saveRecord函数。这很糟糕 – 这可能会导致我们在稍后的函数中重复我们的代码。因此,将任何可能需要调用多次或从另一个函数中调用的任何东西放到帮助程序文件中是一种更好的做法。

  2. 将帮助程序文件的默认内容替换为:
    ({
        navigateTo: function(component, recId) {
            var navEvt = $A.get("e.force:navigateToSObject");
            navEvt.setParams({
                "recordId": recId
            });
            navEvt.fire();
        }
    })
    
    这个函数只是调用内置的平台事件force:navigateToSObject,传递我们从recordSave的回调中得到的recordId。
  3. 保存文件。
  4. 切换回PropertyDialogController.js。
  5. 在resultsToast.fire()之后的新行中添加以下内容:在回调的成功状态(在第40行附近):
    var recId = result.recordId;
    helper.navigateTo(component, recId);
    
  6. 保存文件,然后返回到您的组织并刷新属性详细信息页面。
  7. 用这些值填写表单:
    • Name: 123 Main St.
    • Beds: 4
    • Baths: 3
    • Price: 500000
    • Status: Pre-Market
  8. 点击提交。

alt text: The record was successfully saved.

你印象深刻吗?你只是保存了一个新的记录而不用写任何Apex代码去做!即使你是一个性格开朗的开发者,也会觉得非常神奇。接下来,让我们完成我们设定的操作并覆盖“新建”按钮。