zoukankan      html  css  js  c++  java
  • Lightning框架示例

    动态建立Lightning组件

    组件化前端开发是Lightning框架的优点之一。在进行Lightning应用开发时,我们可以将组件进行嵌套、引用,从而实现模块的封装和重用,提高开发效率。

    组件的嵌套和引用最常用的方法是在Lightning组件中直接使用组件标签,比如:

    <aura:component controller="ExampleController">
        <c:ExampleChildComponent />
    </aura:component>
    

    在这段代码中,正在进行开发的Lightning组件中静态地引用了“ExampleChildComponent”组件。

    另一种方法就是在控制器或辅助函数的Javascript代码中动态建立组件,主要使用“$A.createComponent()”函数(官方文档)。

    本文将通过一个实例来阐述如何动态建立组件。

    示例目标

    本示例的目标是实现一个类似于Salesforce标准列表视图的应用,可以显示一个电话为“1234567890”的“客户”对象的列表,并可以更改它们的名字。

    示例将包含以下几个部分:

    • Lightning应用
    • 列表组件,用于显示“客户”对象的列表
    • 更新组件,在运行时动态建立,包括一个文本框和提交按钮,接收用户的输入并将输入的值更新到“客户”对象的“名字”字段中
    • Lightning事件,用于在组件中传递数据

    建立Lightning组件的Apex控制器

    建立一个Apex类,取名为“AccountListViewController”,作为即将建立的Lightning组件的控制器。在这个Apex类中我们将编写“客户”对象相关的函数,包括了查找“客户”对象和更新“客户”对象。

    为了演示简单起见,我们略去异常处理以及单元测试等代码。

    代码如下:

    public class AccountListViewController {
    	@AuraEnabled
        public static String loadAccounts() {
            List<Account> accountList = [SELECT Id, Name, AccountNumber, Phone, Website FROM Account WHERE Phone = '1234567890'];
            
            return JSON.serialize(accountList);
    	}
        
        @AuraEnabled
        public static String updateAccount(String jsonString) {
            Account acc = (Account)JSON.deserialize(jsonString, Account.class);
            
            update acc;
            
            return 'Success';
    	}
    }
    

    建立更新事件

    为了在两个组件中传递数据(列表组件、更新组件),需要建立一个Lightning事件,取名为“accountListViewEvt”,其中包含了“客户”对象的ID和名字两个属性。

    代码如下:

    <aura:event type="COMPONENT">
        <aura:attribute name="accountId" type="String" />
        <aura:attribute name="accountName" type="String" />
    </aura:event>
    

    建立更新组件

    建立一个新的Lightning组件,命名为“AccountNameUpdateCmp”,用于接收用户的输入,其中包含:

    • 两个属性:“客户”的ID和名字
    • 输入框,用于让用户输入“客户”名字
    • 提交按钮,用于调用更新的函数
    • 事件注册,用于调用刚才建立的更新事件,传递数据

    组件外观代码如下:

    <aura:component >
        <aura:attribute name="accountId" type="String" access="public" />
        <aura:attribute name="accountName" type="String" access="public" />
    
        <aura:registerEvent name="accountListViewEvt" type="c:accountListViewEvt" />
    
        <div class="slds-form slds-form_horizontal">
    
            <div class="slds-form-element">
                <label class="slds-form-element__label">名字</label>
                <div class="slds-form-element__control">
                    <lightning:input value="{!v.accountName}" />
                </div>
            </div>
    
            <div class="slds-form-element">
                <div class="slds-form-element__control">
                    <lightning:button variant="brand" label="Submit" onclick="{!c.submit}" />
                </div>
            </div>
        </div>
    </aura:component>
    

    组件控制器代码如下:

    ({
    	submit : function(component, event, helper) {
    		var cmpEvent = component.getEvent("accountListViewEvt");
    
    		cmpEvent.setParams({
    			'accountId': component.get('v.accountId'),
    			'accountName': component.get('v.accountName'),
    		});
    
    		cmpEvent.fire();
    	},
    })
    

    从上面可以看出:

    • 此组件没有相关联的Apex控制器,只负责接收用户输入的值,作为“客户”对象的名字
    • 当用户点击提交按钮后,在控制器中使用“component.getEvent()”函数启用更新事件,并用“fire()”函数将用户的输入发送出去。

    接下来要建立的列表组件将动态创建此组件,并在此组件执行结束后接收用户的输入(通过更新事件发送的值)。

    建立列表组件

    建立一个Lightning组件,取名为“AccountListViewCmp”,并在其中建立:

    • 一个列表类型的属性,用于存储要显示的“客户”对象
    • 一个表格,用于显示“客户”对象的内容
    • 一个初始化函数,用于读取“客户”对象
    • 一个创建更新组件的函数,动态建立更新组件
    • 一个事件处理函数,用于在更新组件提交后接收用户的输入,并通过Apex控制器更新“客户”对象的名字

    组件外观的代码如下:

    <aura:component controller="AccountListViewController">
        <!-- 将需要动态建立的组件作为依赖注册在此 -->
        <aura:dependency resource="c:AccountNameUpdateCmp" />
    
        <!-- Aura.Component[] 类型的属性用于保存动态建立的组件 -->
        <aura:attribute name="updateWidget" type="Aura.Component[]" access="public" />
        
        <aura:attribute name="accountList" type="Object[]" access="public" />
             
        <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    
        <!-- 在更新事件启动之后,接收事件传递的值,并更新“客户”对象 -->
        <aura:handler name="accountListViewEvt" event="c:accountListViewEvt" action="{!c.handleUpdate}"/>
    
        <!-- 这个部分默认是隐藏的,其中包括了变量“updateWidget”,所以更新组件建立后将被显示在此 -->
        <div>
            <section role="dialog" tabindex="-1" aria-modal="true" class="slds-modal" aura:id="modalBody">
                <div class="slds-modal__container">
                    <div class="slds-modal__content slds-p-around_medium">
                        {!v.updateWidget}
                    </div>
                </div>
            </section>
            <div class="slds-backdrop" aura:id="modalBackdrop"></div>
        </div>
    
        <!-- 列表的外观,用于显示“客户”对象 -->
        <table class="slds-table slds-table_bordered">
            <thead>
                <tr class="slds-text-title">
                    <th scope="col">
                        <div class="slds-truncate" title="客户名">客户名</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="电话">电话</div>
                    </th>
                </tr>
            </thead>
            <tbody>
                <aura:iteration items="{!v.accountList}" var="acc">
                	<tr>
                        <td>
                            <div class="slds-truncate">
                                <a class="slds-th__action" href="javascript:void(0);" role="button"
                                	onclick="{!c.startUpdate}" data-account-id="{!acc.Id}" data-account-name="{!acc.Name}">
                                    {!acc.Name}
                                </a>
                            </div>
                        </td>
                        <td>
                            <div class="slds-truncate">
                                {!acc.Phone}
                            </div>
                        </td>
                	</tr>
                </aura:iteration>   
            </tbody>
        </table>
        
    </aura:component>
    

    组件的控制器代码如下:

    ({
    	doInit : function(component, event, helper) {
            helper.loadAccountList(component, helper);
    	},
        
        startUpdate : function(component, event, helper) {
        	var accountId = event.currentTarget.dataset.accountId;
            var accountName = event.currentTarget.dataset.accountName;
            
            // 动态建立更新组件,并将“客户”的ID和当前的“名字”的值传递到更新组件中
            $A.createComponent(
                "c:AccountNameUpdateCmp",
                {
                    "accountId": accountId,
                    "accountName": accountName
                },
                function(newComponent, status, errorMessage){
                    if (status === "SUCCESS") {
                        component.set('v.updateWidget', newComponent);
    
                        var modalBody = component.find('modalBody');
                        var modalBackdrop = component.find('modalBackdrop');
                        $A.util.addClass(modalBody,'slds-fade-in-open');
                        $A.util.addClass(modalBackdrop,'slds-backdrop--open');
                    }
                }
            );
        },
        
        handleUpdate : function(component, event, helper) {
            // 在更新事件结束后,得到其中包含的值,即“客户”对象的ID和用户输入作为对象新名字的值
            var updateInfo = {
                Id: event.getParam('accountId'),
                Name: event.getParam('accountName')
            };
            
            // 调用Apex控制器的代码进行更新
    		var action = component.get('c.updateAccount');
            action.setParams({
                jsonString: JSON.stringify(updateInfo)
            });
            action.setCallback(this, function(response) {
                var result = response.getReturnValue();
                if (result == 'Success') {
                    helper.loadAccountList(component, helper);
                }
            });
            $A.enqueueAction(action);  
            
    		var modalBody = component.find('modalBody');
    		var modalBackdrop = component.find('modalBackdrop');
    		$A.util.removeClass(modalBody,'slds-fade-in-open');
    		$A.util.removeClass(modalBackdrop,'slds-backdrop--open');
        },
    })
    

    辅助函数代码如下:

    ({
    	loadAccountList : function(component, helper) {
    		var action = component.get('c.loadAccounts');
            action.setCallback(this, function(response) {
                var result = response.getReturnValue();
                var accountList = JSON.parse(result);
                component.set('v.accountList', accountList);
            });
            $A.enqueueAction(action);  
    	}, 
    })
    

    建立Lightning应用

    建立一个Lightning应用,取名为“AccountListViewApp”,包含了刚才的列表组件。代码如下:

    <aura:application extends="force:slds">
        <c:AccountListViewCmp />
    </aura:application>
    

    小结

    动态建立组件可以实现组件的灵活复用。

    比如上面示例中的更新组件,我们可以再增加几个属性,扩展为通用的文本更新组件。它没有相关联的Apex控制器,没有很多逻辑,只负责接收和发送文本框中的数据(相关的逻辑由调用此组件的代码来处理)。

    当然,动态建立的组件本身也可以包括Apex控制器和相关的逻辑,但是这样会增加和服务器端的通讯次数。为了保证运行效率,我们最好让它们只负责客户端的操作。

    Salesforce对于动态建立的组件有垃圾回收机制,这只限于组件被创建后赋值给了“Aura.Component[]”类型的属性。当此组件不再被使用时,会被自动清除。

    对于更新“客户”对象的“名字”功能,上面的示例有些过度设计了。但是在实际应用中,可以对和该示例类似的结构进行扩展,用于更复杂的场景,比如对于外部数据的CRUD操作(CRUD操作需要通过网络服务使用,Salesforce的默认功能可能无法使用)。

  • 相关阅读:
    [Docker] Windows 宿主环境下,共享或上传文件到容器的方法
    [Docker]
    [Docker]
    [Docker]
    [Windows]
    [Linux] 树莓派 4B 安装 Ubuntu 19.10 (Eoan Ermine) IOT 版
    [Linux]
    [.Net] 什么是线程安全的并发集合
    [IOT]
    c++库大全
  • 原文地址:https://www.cnblogs.com/chengcheng0148/p/create_dynamic_lightning_components.html
Copyright © 2011-2022 走看看