标签:uil attribute 控制 vat lis model ted containe this
在 Lightning 框架中,如果我们想要使用第三方的组件,可以将它们包含在 Lightning Container 模块中。
Lightning Container 会将内部的组件包含在一个 iframe 中,并且提供了若干函数让其内部的组件和外部的 Lightning 应用进行通信。
它要求内部的组件是作为“静态资源(static resource)”上传到 Salesforce 中。
它的语法本质上是调用静态资源的 URL 路径。
举个例子,我们已经有了一个 Vue 应用,它的入口文件是 index.html,我们将它上传到 Salesforce 的静态资源,名字叫 “testApp”,那么调用它的方式如下:
<lightning:container src="{!$Resource.testApp + '/index.html'}" />Lightning Container 提供了 NPM 包,可以让第三方组件调用 API,从而和 Lightning 组件进行通信。
我们以两个 Vue-cli 例子程序来说明:
初始化 Vue-cli 项目,然后安装 NPM 包:
npm install lightning-container --save在 main.js 文件中加入以下两行:
import LCC from 'lightning-container'
Vue.prototype.$LCC = LCC这样,我们就可以在其他的组件中引用模块了,语法如下:
this.$LCC在命令行中运行以下命令即可将 Vue 的应用编译到 “dist” 文件夹下:
npm run build然后我们将 “dist” 文件夹下的内容打包成 zip 文件,上传到 Salesforce 中作为静态资源。
Vue-cli 的应用默认的入口是 index.html 文件。
在这个通信的演示程序中,我们要达到的目标是把文字在 Lightning 组件和 Vue 应用中相互发送。
在 Vue 项目中,在 “src/components” 文件夹中新建 Vue 组件,名为 “Messaging.vue”,代码如下:
<template>
  <div>
    <h3>通信演示</h3>
    
    <div>
      发送给 Lightning Component:
      <input type="text" id="text-input-to-Lc" class="slds-input" v-model="msgToLC" />
      <button id="sendBtn" class="slds-button slds-button--neutral" v-on:click="sendMessage">发送到 Lightning Component</button>
    </div>
    
    <div>
      从 Lightning Component 接收的信息:
      <input type="text" id="text-input-from-Lc" class="slds-input" v-model="msgFromLC" />
    </div>
  </div>
</template>
<script>
export default {
    data () {
        return {
        msgToLC: '',
        msgFromLC: ''
        }
    },
    mounted: function() {
        this.$LCC.addMessageHandler(this.receiveMessage); // 使用 addMessageHandler() 函数定义如何接收从 Lightning 组件中传来的数据
    },
    methods: {
        receiveMessage: function(message) {
            this.msgFromLC = message.value;
        },
        sendMessage: function() {
            // 使用 sendMessage() 函数发送信息给 Lightning 组件
            this.$LCC.sendMessage({name: "Message To LC", value: this.msgToLC})
        }
    }
}
</script>在 Vue 项目的 “src/router” 文件夹下,修改 “index.js” 文件,将刚才建立的 Vue 组件定义为默认的路径:
import Messaging from '@/components/Messaging'
export default new Router({
    routes: [
    {
        path: '/',
        name: 'Messaging',
        component: Messaging
    },
    ]
})编译 Vue 应用,然后上传到 Salesforce 中,作为静态资源,名为 “VueApplication”。
在 Salesforce 中新建 Lightning 组件:
<aura:component access="global">
    <aura:attribute access="private" name="messageToSend" type="String" default=""/>
    <aura:attribute access="private" name="messageReceived" type="String" default=""/>
    
    <div>
        <lightning:input name="messageToSend" value="{!v.messageToSend}" label="发送给 Vue 应用: "/>
        <lightning:button label="Send" onclick="{!c.sendMessage}"/>
        <br/>
        <lightning:input value="{!v.messageReceived}" label="接收自 Vue 应用: "/>
        <br/>
    
        <!-- 使用 lightning:container 来调用静态资源中的 Vue 应用,并定义在收到它的信息时使用的函数 -->
        <lightning:container aura:id="vueApp"
                             src="{!$Resource.vueApplication + '/index.html'}"
                             onmessage="{!c.handleMessage}"/>
    </div>
</aura:component>定义控制器:
({
    /*
     * 从 Lightning 组件中发送信息
     */
    sendMessage : function(component, event, helper) {
        var msg = {
            name: "Message From LC",
            value: component.get("v.messageToSend")
        };
      
        component.find("vueApp").message(msg);
    },
    
    /*
     * 接收从 Vue 应用中发送的信息
     */ 
    handleMessage: function(component, event, helper) {
        var value = event.getParams().payload.value;
   
        component.set("v.messageReceived", value);        
    },
})当我们使用这个 Lightning 组件时,它会自动调用 Vue 应用,然后可以将文字在两个应用之间发送和接收。
当我们查看页面的源代码时,可以看到,lightning:container 中的内容被放在了一个 iframe 中,所以我们的 Vue 应用其实是封装起来的。
在接下来的应用中,我们要从 Vue 应用中调用 Apex 函数。
在 Salesforce 中建立 Apex 函数:
global without sharing class VueController {
    @RemoteAction
    global static Account[] getAccounts(String searchString) {
        return [SELECT Id, Name, Phone, Type, NumberOfEmployees FROM Account Limit 10];
    }
}为了调用 Apex 函数,我们在 Vue 应用中需要一个特殊的设置。在 “dist” 文件夹下建立一个名为 “manifest.json” 的文件,内容如下:
{
    "landing-pages" : [
        {
            "path": "index.html",
            "apex-controller": "VueController"
        }
    ]
}在 Vue 应用中建立一个名为 “AccountList” 的组件:
<template>
  <div>
    <h3>接收到的数据:</h3>
    
    <ul>
      <li v-for="item in accounts">
        {{ item.Name }}
      </li>
    </ul>
  </div>
</template>
<script>
export default {
    data () {
        return {
            accounts: [],
        }
    },
    mounted: function() {
        this.getAccounts();
    },
    methods: {
        getAccounts: function() {
            // 使用 callApex() 函数来调用相应的函数
            this.$LCC.callApex("VueController.getAccounts", 
            {
            searchString: ''
            }, 
            this.handleResult, 
            {});
        },
        handleResult: function(result) {
            this.accounts = result;
        },
    }
}
</script>这样,在用 lightning:container 在 Lightning 组件中执行 Vue 应用时,Vue 应用会直接调用 Apex 函数,然后给出结果。
Lightning Container 机制和 Locker Service 机制都是对 Lightning 组件的安全进行提高,将不同来源(命名空间等)的组件分别封装。
Lightning Container 是基于 iframe 的,它将第三方的组件或应用封装在 iframe 中,而 Locker Service 则不需要这样,它是将不同的组件放在同一个 DOM 树中,将不同的 DOM 元素封装起来。这是两者最大的不同,从而也决定了它们不同的特性:
标签:uil attribute 控制 vat lis model ted containe this
原文地址:https://www.cnblogs.com/chengcheng0148/p/lightning_container_introduction.html