为用户界面有条件地呈现Visualforce页面
在上一步中,我们让服务器从Visualforce更新标准样式表。虽然页面看起来不错,但只要做一点工作,就可以更接近Lightning Experience的外观。所以这个练习我们将会:
- 确定用户正在使用的UX环境(Salesforce Classic或Lightning Experience)
- 将条件呈现逻辑添加到页面以提供来自SLDS的其他样式
- 使用SLDS中的其他类来调整页面元素
第1部分 – 将用户主题的检查添加到Apex控制器
当用户在Salesforce中请求页面时,系统可以识别用户是处于Salesforce Classic还是Lightning Experience。有了这些知识,我们可以包含或排除页面的区域,以确保用户的正确体验。
- 在开发人员控制台中,单击 File > Open > Classes 然后选择DreamhouseProspects Apex 类,然后单击 Open.
在public String sortOrder {set; get;}
行,添加下面的方法来检测用户的当前主题:public Boolean getIsClassic() { return (UserInfo.getUiThemeDisplayed() == 'Theme3'); }
- Apex类现在应该是这样的:
public with sharing class DreamhouseProspects { public String sortOrder {set; get;} public Boolean getIsClassic() { return (UserInfo.getUiThemeDisplayed() == 'Theme3'); } public List<Lead> getLeads() { if (sortOrder == null) { sortOrder = 'LastName'; } return Database.query('SELECT Description,Email,FirstName,Id,LastName,Phone FROM Lead WHERE Company=\'Dreamhouse\' ORDER BY '+sortOrder); } public pageReference sortList() { getLeads(); return null; } }
- 保存Apex类并关闭其在开发者控制台中的标签。
第2部分 – 根据用户的主题添加动态块
- 在开发者控制台中,通过在打开的<apex:page>标记之后添加一个新行,将指令添加到DreamHouseLeads.vfp页面:
<apex:slds />
- 将
rendered="{! !isClassic}"
添加到<apex:slds />
标签中:<apex:slds rendered="{! !isClassic}" />
因此,如果用户在Lightning中,则可以使用来自SLDS的样式和标记,而在Classic中,该页面仍然像以前一样。
第3部分 – 添加SLDS标题
页面的自动样式看起来相当不错,但页面标题与Lightning Experience中的其他页面不完全相同。请注意,它缺少标题旁边的标准图标,选择列表看起来像标准浏览器选择。此外,选择和排序按钮太靠近表格。如果没关系,那就巧妙地移动。为了这个项目的目的,让我们继续前进,使之与Lightning Experience完全匹配。
- 交换<apex:sectionHeader>和<apex:form>元素(在第4行和第5行左右)。
为了有条件地传递页面的元素,我们需要能够用<apex:outputPanel>标签包装完整的元素。所以,我们刚刚在窗体中移动了节标题,以便我们可以用New按钮,选择列表和排序按钮将它们包装在一起。
- 使用<apex:outputPanel rendered =“{!isClassic}”> … </ apex:outputPanel>将整个代码从<apex:sectionHeader>包装到<apex:commandButton>(从第5-14行开始)。你的代码现在应该是这样的:
<apex:page controller="DreamhouseProspects" lightningStylesheets="true"> <apex:slds rendered="{! !isClassic}" /> <apex:pageBlock > <apex:form > <apex:outputPanel rendered="{!isClassic}"> <apex:sectionHeader title="Leads" subtitle="Home"/> <div style="text-align:center;"> <apex:commandButton action="{!URLFOR($Action.Lead.New)}" value="New"/> </div> <apex:outputLabel value="Sort: " for="sortList" /> <apex:selectList value="{! sortOrder}" size="1" id="sortList"> <apex:selectOption itemvalue="LastName" /> <apex:selectOption itemvalue="FirstName" /> </apex:selectList> <apex:commandButton value="Sort Table" action="{!sortList}" reRender="leads_list"/> </apex:outputPanel> <apex:pageBlockTable value="{! leads }" var="ct" id="leads_list"> <apex:column headerValue="First Name"> <apex:outputLink value="/{! ct.Id}">{! ct.FirstName }</apex:outputLink> </apex:column> <apex:column value="{! ct.LastName }"/> <apex:column value="{! ct.Email }"/> <apex:column value="{! ct.Phone }"/> </apex:pageBlockTable> </apex:form> </apex:pageBlock> </apex:page>
- 保存页面并重新加载到浏览器中。
您已经丢失了整个页面标题和按钮,因为现在只会在{!isClassic}解析为true时才呈现。所以,现在我们可以添加一个匹配Lightning Experience的页面标题。
虽然我们完全可以创建自己的HTML标记和CSS,但Visualforce开发人员可以做的更多,我们的目标是确保页面看起来与Lightning Experience完全一样。这正是Salesforce UX团队创建SLDS的原因。我们可以简单地将标记从SLDS复制并粘贴到我们的页面中,并修改其占位符内容以显示我们所需的内容。
- 导航到SLDS站点。点击侧边栏中的组件,然后点击页面标题,熟悉标记和样式。
您看到的每个组件的预览都是由您在预览下方看到的标记构建的。这是您可以简单地复制/粘贴,然后修改的标记。
但是,请注意,对于每个组件(在本例中为页眉),页面的右侧都有变体和状态。这些是所选组件的不同版本。当您选择变体或状态时,示例标记会更改。所以请确保您正在复制所需的变体或状态。
为了让你更容易,我们已经复制了Object Home变体,并对其进行了修改。
- 返回到开发者控制台,在最后一步添加的</ apex:outputPanel>(可能是第16行)之后的新行中添加以下代码:
<apex:outputPanel rendered="{! !isClassic}"> <div class="slds-page-header"> <div class="slds-grid"> <div class="slds-col slds-has-flexi-truncate" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <div class="slds-media slds-no-space slds-grow"> <div class="slds-media__figure"> <svg class="slds-icon slds-icon-standard-user .slds-icon_small" aria-hidden="true"> <use xlink:href="{!URLFOR($Asset.SLDS, 'assets/icons/standard-sprite/svg/symbols.svg#lead')}"></use> </svg> </div> <div class="slds-media__body"> <p class="slds-text-title_caps slds-line-height_reset">Lead</p> <h1 class="slds-page-header__title slds-m-right_small slds-align-middle slds-truncate" title="this should match the Record Title">Home</h1> </div> </div> <div class="slds-grid slds-grid_vertical-align-end slds-m-vertical_small"> <div class="slds-size_1-of-6 "> <apex:outputLabel value="Sort: " for="sortListLightning" styleClass="slds-form-element__label" /> <div class="slds-select_container"> <apex:selectList value="{! sortOrder}" size="1" id="sortListLightning" styleClass="slds-select"> <apex:selectOption itemvalue="LastName" /> <apex:selectOption itemvalue="FirstName" /> </apex:selectList> </div> </div> <div class="slds-no-flex slds-m-left_x-large"> <apex:commandButton value="Sort" action="{!sortList}" reRender="leads_list" styleClass="slds-button slds-button_neutral"/> </div> </div> </div> <div class="slds-col slds-no-flex slds-grid slds-align-top"> <apex:commandButton action="{!URLFOR($Action.Lead.New)}" value="New" styleClass="slds-button slds-button_neutral"/> </div> </div> </div> </apex:outputPanel>
- 保存文件并在Lightning Experience中重新加载页面以查看您的更改。
现在,你不得不承认这很酷,对吗?通过对页面进行一些更改,我们现在可以在Lightning Experience中正确呈现标准Visualforce页面,同时在Salesforce Classic中保持其原始外观。以防万一你的页面倒下,并轰然倒地…这是代码应该看起来的样子:
<apex:page controller="DreamhouseProspects" lightningStylesheets="true"> <apex:slds rendered="{! !isClassic}"/> <apex:pageBlock > <apex:form > <apex:outputPanel rendered="{! isClassic}"> <apex:sectionHeader title="Leads" subtitle="Home"/> <div style="text-align:center;"> <apex:commandButton action="{!URLFOR($Action.Lead.New)}" value="New"/> </div> <apex:outputLabel value="Sort: " for="sortList" /> <apex:selectList value="{! sortOrder}" size="1" id="sortList"> <apex:selectOption itemvalue="LastName" /> <apex:selectOption itemvalue="FirstName" /> </apex:selectList> <apex:commandButton value="Sort Table" action="{!sortList}" reRender="leads_list"/> </apex:outputPanel> <apex:outputPanel rendered="{! !isClassic}"> <div class="slds-page-header"> <div class="slds-grid"> <div class="slds-col slds-has-flexi-truncate" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <div class="slds-media slds-no-space slds-grow"> <div class="slds-media__figure"> <svg class="slds-icon slds-icon-standard-user .slds-icon_small" aria-hidden="true"> <use xlink:href="{!URLFOR($Asset.SLDS, 'assets/icons/standard-sprite/svg/symbols.svg#lead')}"></use> </svg> </div> <div class="slds-media__body"> <p class="slds-text-title_caps slds-line-height_reset">Lead</p> <h1 class="slds-page-header__title slds-m-right_small slds-align-middle slds-truncate" title="this should match the Record Title">Home</h1> </div> </div> <div class="slds-grid slds-grid_vertical-align-end slds-m-vertical_small"> <div class="slds-size_1-of-6 "> <apex:outputLabel value="Sort: " for="sortListLightning" styleClass="slds-form-element__label" /> <div class="slds-select_container"> <apex:selectList value="{! sortOrder}" size="1" id="sortListLightning" styleClass="slds-select"> <apex:selectOption itemvalue="LastName" /> <apex:selectOption itemvalue="FirstName" /> </apex:selectList> </div> </div> <div class="slds-no-flex slds-m-left_x-small"> <apex:commandButton value="Sort" action="{!sortList}" reRender="leads_list" styleClass="slds-button slds-button_neutral"/> </div> </div> </div> <div class="slds-col slds-no-flex slds-grid slds-align-top"> <apex:commandButton action="{!URLFOR($Action.Lead.New)}" value="New" styleClass="slds-button slds-button_neutral"/> </div> </div> </div> </apex:outputPanel> <apex:pageBlockTable value="{! leads }" var="ct" id="leads_list"> <apex:column headerValue="First Name"> <apex:outputLink value="/{! ct.Id}">{! ct.FirstName }</apex:outputLink> </apex:column> <apex:column value="{! ct.LastName }"/> <apex:column value="{! ct.Email }"/> <apex:column value="{! ct.Phone }"/> </apex:pageBlockTable> </apex:form> </apex:pageBlock> </apex:page>