继上一篇博文,已经介绍过,怎样去初始化一个组件,怎样通过一个记录上的button调用组件,以及组件中的各个组块之间起什么作用等。
本篇继续延续上一个文章,简单的搭建一个lightning页面的Demo出来。
批量添加订单产品,我相信这个场景大家应该都有遇到过,可能会涉及到产品的检索,分页。添加价格,数量等操作。下面我们通过lightning的模块实现该功能,主要是体验lightning中的数据传递。
Comment Code
<aura:component implements="flexipage:availableForAllPageTypes,force:appHostable,flexipage:availableForRecordHome,force:lightningQuickActionWithoutHeader,force:hasSObjectName,force:hasRecordId" controller="AP_OrderItems">
<style>
.slds-modal__container {
max-width: 80rem !important;
width:80% !important;
}
style>
<aura:attribute name="toggleSpinner" type="boolean" default="false"/>
<aura:attribute name="recordId" type="String"/>
<aura:attribute name="product" type="Product__c" default="{ 'sobjectType' : 'Product__c'}"/>
<aura:attribute name="productListAdd" type="Object[]"/>
<aura:attribute name="addListFlag" type="boolean" default="false"/>
<aura:attribute name="productListSerach" type="Object[]"/>
<aura:handler name="init" value="this" action="{!c.doInit}"/>
<article class="slds-card">
<div class="slds-card__header slds-grid">
<header class="slds-media slds-media_center slds-has-flexi-truncate">
<div class="slds-media__body">
<h1>
<lightning:icon iconName="action:clone"/>
<span class="slds-text-heading_small" style="font-size: 24px; margin-left: 15px;">添加订单产品span>
h1>
div>
<div class="slds-no-flex">
<button class="slds-button slds-button_brand" onclick="{!c.doSearch}">搜索button>
div>
header>
div>
<div class="slds-card__body slds-card__body_inner">
<article class="slds-card">
<div class="slds-card__body slds-card__body_inner">
<table class="slds-table slds-table_fixed-layout slds-table_bordered slds-no-row-hover slds-table_cell-buffer">
<tr class="slds-text-title_caps">
<th scope="col">
<div class="slds-truncate" title="Product_Name">
<lightning:input label="产品名称:" value="" type="text" name="Product_Name" aura:id="Product_Name"/>
div>
th>
<th scope="col">
<div class="slds-truncate" title="ProductID">
<lightning:input label="产品标识码:" value="" type="text" name="ProductID" aura:id="ProductID"/>
div>
th>
tr>
table>
div>
article>
<article class="slds-card slds-card_boundary">
<div class="slds-card__header slds-grid">
<header class="slds-media slds-media_center slds-has-flexi-truncate">
<div class="slds-media__figure">
<span class="slds-icon_container slds-icon-standard-contact" title="description of icon when needed">
span>
div>
<div class="slds-media__body">
<h2>
<span class="slds-text-heading_small">查询结果span>
h2>
div>
header>
<div class="slds-no-flex">
<button class="slds-button slds-button_brand" onclick="{!c.add}">添加button>
div>
div>
<div class="slds-card__body slds-card__body_inner">
<div style="overflow-y: scroll;display: block;height: 300px">
<table class="slds-table slds-table_fixed-layout slds-table_bordered slds-no-row-hover slds-table_cell-buffer">
<thead>
<tr class="slds-text-title_caps">
<th scope="col" style="width:3.25rem;" class="slds-text-align--right">
<ui:inputCheckbox aura:id="se" change="{!c.selectAll}" class="pro"/>
th>
<th scope="col" style="width:30%;">
<div class="slds-truncate" title="Name">产品名称div>
th>
<th scope="col" style="width:15%;">
<div class="slds-truncate" title="Company">产品标识码div>
th>
tr>
thead>
<tbody>
<aura:iteration items="{!v.productListSerach}" var="prod">
<tr class="slds-hint-parent">
<td>
<ui:inputCheckbox aura:id="box" value="{!prod.flag}"/>
td>
<td>
<div class="slds-truncate" title="">
<ui:outputTextArea value="{!prod.product.Name}" click="{!c.showProduct}"/>
div>
td>
<td>
<div class="slds-truncate" title="">
<p>{!prod.product.Product_Code__c}p>
div>
td>
tr>
aura:iteration>
tbody>
table>
div>
div>
article>
div>
article>
<aura:if isTrue="{!v.addListFlag}">
<article class="slds-card slds-card_boundary">
<div class="slds-card__header slds-grid">
<header class="slds-media slds-media_center slds-has-flexi-truncate">
<div class="slds-media__figure">
<span class="slds-icon_container slds-icon-standard-contact" title="description of icon when needed">
span>
div>
<div class="slds-media__body">
<h2>
<span class="slds-text-heading_small">产品列表span>
h2>
div>
header>
<div class="slds-no-flex">
<button class="slds-button slds-button_brand" onclick="{!c.remove}">移除button>
div>
div>
<div class="slds-card__body slds-card__body_inner">
<table class="slds-table slds-table_fixed-layout slds-table_bordered slds-no-row-hover slds-table_cell-buffer" >
<thead>
<tr class="slds-text-title_caps">
<th scope="col" style="width:3.25rem;" class="slds-text-align--right">
<ui:inputCheckbox aura:id="pro" change="{!c.selectAll}" class="pro2"/>
th>
<th scope="col" style="width:24%;">
<div class="slds-truncate" title="Name">产品名称div>
th>
<th scope="col" style="width:8%;">
<div class="slds-truncate" title="Email">产品号div>
th>
<th scope="col" style="width:8%;">
<div class="slds-truncate" title="Email">数量div>
th>
<th scope="col" style="width:9%;">
<div class="slds-truncate" title="Email">单价div>
th>
tr>
thead>
<tbody>
<aura:iteration items="{!v.productListAdd}" var="productAdd">
<tr class="slds-hint-parent">
<td>
<ui:inputCheckbox aura:id="box1" value="{!productAdd.flag}"/>
td>
<td>
<div class="slds-truncate" title="">
<ui:outputText value="{!productAdd.product.Name}"/>
div>
td>
<td>
<ui:outputText value="{!productAdd.product.Product_Code__c}"/>
td>
<td>
<div class="slds-truncate" title="">
<ui:inputNumber label=" " value="{!productAdd.num}" />
div>
td>
<td>
<div class="slds-truncate" title="">
<ui:inputNumber label=" " value="{!productAdd.Price}" />
div>
td>
tr>
aura:iteration>
tbody>
table>
div>
<footer class="slds-card__footer">
<lightning:button class="slds-button slds-button_brand" label="提交" onclick="{!c.save}"/>
<lightning:button class="slds-button slds-button_neutral" label="取消" onclick="{!c.cancel}"/>
footer>
article>
aura:if>
<aura:if isTrue="{!v.toggleSpinner}">
<div class="slds-spinner_container">
<div class="slds-spinner--brand slds-spinner slds-spinner--large slds-is-relative" role="alert">
<span class="slds-assistive-text">Loadingspan>
<div class="slds-spinner__dot-a">div>
<div class="slds-spinner__dot-b">div>
div>
div>
aura:if>
aura:component>
js Controller
({
doInit : function(component, event, helper) {
helper.init(component);
},
doSearch : function(component, event, helper) {
console.log("serach function");
helper.showSpinner(component);
var productName= component.find("Product_Name").get("v.value");
var productID = component.find("ProductID").get("v.value");
helper.serach(component,productName,productID);
helper.hideSpinner(component);
},
add : function(component, event, helper) {
var prolist = component.get("v.productListSerach");
var productsAdd = component.get("v.productListAdd");
//打勾的list
for(var i = 0 ; i < prolist.length ; i ++ )
{
if(prolist[i].flag)
{
prolist[i].flag = false;
productsAdd.unshift(prolist[i]);
prolist.splice(i,1);
i--;
}
}
component.set("v.productListSerach", prolist);
component.set("v.productListAdd", productsAdd);
// 判断是否展示选中的产品块
if(component.get("v.productListAdd").length > 0)
component.set("v.addListFlag", true);
else
component.set("v.addListFlag", false);
},
remove : function(component, event, helper)
{
var proserachlist = component.get("v.productListSerach");
var prolist = component.get("v.productListAdd");
//打勾的list
for(var i = 0 ; i < prolist.length ; i ++ )
{
//选中移除
if(prolist[i].flag)
{
prolist[i].flag = false;
proserachlist.unshift(prolist[i]);
prolist.splice(i,1);
i--;
}
}
component.set("v.productListSerach", proserachlist);
component.set("v.productListAdd", prolist);
// 判断是否展示选中的产品块
if(component.get("v.productListAdd").length > 0)
component.set("v.addListFlag", true);
else
component.set("v.addListFlag", false);
},
save : function(component, event, helper){
// 先对选中的需要添加的产品进行判断
var prolist = component.get("v.productListAdd");
var flag = false;
var addpro = new Array();
for(var i = 0 ; i < prolist.length ; i ++ ){
if(prolist[i].flag){
flag = true;
addpro.unshift(prolist[i]);
}
}
if(flag)
helper.saveDate(component,addpro);
else
alert("请选择需要添加的产品");
},
cancel : function(component, event, helper){
var dismissActionPanel = $A.get("e.force:closeQuickAction");
dismissActionPanel.fire();
},
selectAll : function(component, event, helper)
{
var flag = event.getSource().get('v.class');
var info;
var prolist;
if(flag == "pro"){
info = "box";
prolist = component.get("v.productListSerach");
}else
{
info = "box1";
prolist = component.get("v.productListAdd");
}
if(prolist.length > 0)
{
//获取标题复选框的值
var selectedHeaderCheck = event.getSource().get("v.value");
//使用“box ”aura id获取表格上的所有复选框(所有迭代值都具有相同的ID)
//返回所有复选框元素的列表
var getAllId = component.find(info);
//alert(getAllId);
//如果本地ID是唯一的(在单个记录的情况下),find()返回组件,不是数组
if(!Array.isArray(getAllId)){
if(selectedHeaderCheck == true)
component.find(info).set("v.value", true);
else
component.find(info).set("v.value", false);
}
else
{
//检查是否选择全部(标题复选框)为真,然后是for循环中的所有表格上的复选框
//并在selectedCount属性中设置所有选中的复选框长度。
//如果值为false,则在其他部分中将所有复选框设为false,以便循环播放
//并选择计数为0
if(selectedHeaderCheck == true)
{
for(var i = 0; i < getAllId.length; i++) {component.find(info)[i].set("v.value", true);} } else { for (var i = 0; i < getAllId.length; i++) {component.find(info)[i].set("v.value", false);} } } } } })
js Helper
({
init : function(component) {
var recordID = component.get("v.recordId")
var action = component.get("c.initProduct");
action.setParams({ orderId : recordID});
action.setCallback(this, function(response) { //获取请求返回状态 var state = response.getState(); //请求成功 if (state === "SUCCESS") { component.set("v.productListAdd",response.getReturnValue()); // 判断是否展示选中的产品块 if(component.get("v.productListAdd").length > 0) component.set("v.addListFlag", true); else component.set("v.addListFlag", false); } //请求不完整 else if (state === "INCOMPLETE") {} //请求出现错误 else if (state === "ERROR") { var errors = response.getError(); if (errors) { if (errors[0] && errors[0].message) console.log("Error message: " + errors[0].message); } else console.log("Unknown error"); } });
$A.enqueueAction(action);
},
serach : function(component,productName,productID) {
var action = component.get("c.searchProducts");
action.setParams({ productName : productName, productId : productID });
action.setCallback(this, function(response) { //获取请求返回状态 var state = response.getState(); //请求成功 if (state === "SUCCESS") { // 过滤重复的元素 component.set("v.productListSerach",response.getReturnValue()); } //请求不完整 else if (state === "INCOMPLETE") {} //请求出现错误 else if (state === "ERROR") { var errors = response.getError(); if (errors) { if (errors[0] && errors[0].message) console.log("Error message: " + errors[0].message); } else console.log("Unknown error"); } });
$A.enqueueAction(action);
},
saveDate : function(component,addpro){
var action = component.get("c.saveProducts");
action.setParams({ innerList : JSON.stringify(addpro), orderId : component.get("v.recordId") });
action.setCallback(this, function(response) { //获取请求返回状态 var state = response.getState(); //请求成功 if (state === "SUCCESS") { alert("添加成功!"); window.location.reload("one.app#/sObject/"+component.get("v.recordId")+"/view"); } //请求不完整 else if (state === "INCOMPLETE") {} //请求出现错误 else if (state === "ERROR") { var errors = response.getError(); if (errors) { if (errors[0] && errors[0].message) console.log("Error message: " + errors[0].message); } else console.log("Unknown error"); } });
$A.enqueueAction(action);
},
// 开启waiting
showSpinner : function(component){
component.set("v.toggleSpinner", true);
},
// 关闭waiting
hideSpinner : function(component){
component.set("v.toggleSpinner", false);
}
})
服务端 Controller
/*
*Author:Alan Li
*Date:2018-08-10
*Function:
*1、添加订单产品
*/
public with sharing class AP_OrderItems {
public class ProductInner
{
@AuraEnabled
public Product__c product;
@AuraEnabled
public Boolean flag;
@AuraEnabled
public Integer num;//数量
@AuraEnabled
public Decimal Price;//折后价格
}
// 初始化
@AuraEnabled
public static ProductInner[] initProduct(String orderId)
{
ProductInner[] innerList = new ProductInner[]{};
Order__c order = [Select Id,(select Id,Product__c from Order_Product__r) from Order__c where Id =: orderId];
if(order.Order_Product__r.size() > 0){
Map proMap = new Map();
Set idSet = new Set();
for(OrderProducts__c orderProduct : order.Order_Product__r){
idSet.add(orderProduct.Product__c);
}
for(Product__c pro : [Select Id,Name,Product_Code__c from Product__c where id in: idSet]){
proMap.put(pro.Id,pro);
}
System.debug('proMap==='+proMap);
for(OrderProducts__c orderProduct : order.Order_Product__r){
System.debug('proMap33==='+orderProduct.Product__c);
System.debug(proMap.get(orderProduct.Product__c));
ProductInner productInner = new ProductInner();
productInner.product =proMap.get(orderProduct.Product__c);
productInner.flag = false;
productInner.num = 0;
productInner.Price = 0;
innerList.add(productInner);
}
System.debug('innerList==='+innerList);
}
return innerList;
}
// 搜索产品
@AuraEnabled
public static ProductInner[] searchProducts(String productName, String productId)
{
List productList = new List();
String sql = 'SELECT Id,Name,Product_Code__c FROM Product__c where CreatedDate != null ';
if(productName != null && productName != '')
{
sql += 'and Name like \'%' + productName + '%\'';
}
if(productId != null && productId != '')
{
sql += 'and Product_Code__c =\'' + productId + '\'';
}
productList = Database.query(sql);
ProductInner[] innerList = new ProductInner[]{};
for(Product__c product : productList)
{
ProductInner productInner = new ProductInner();
productInner.product = product;
productInner.flag = false;
productInner.num = 0;
productInner.Price = 0;
innerList.add(productInner);
}
return innerList;
}
// 保存
@AuraEnabled
public static void saveProducts(String innerList, String orderId)
{
Order__c order = [Select Id from Order__c where Id =: orderId];
AP_OrderItems.ProductInner[] jsonApex = (AP_OrderItems.ProductInner[])JSON.deserialize(EncodingUtil.urlDecode(innerList,'utf_8'),AP_OrderItems.ProductInner[].class);
List orderProductList = new List();
for(ProductInner innerPro : jsonApex){
OrderProducts__c orderProduct = new OrderProducts__c();
orderProduct.Product__c = innerPro.product.Id;
orderProduct.Order__c = order.Id;
orderProductList.add(orderProduct);
}
insert orderProductList;
}
}
涉及对象:
实现效果:
总结:这个一个简单的Demo页面,UI没经过涉及的简版,并且功能上也是比较简单的,只是实现了批量添加订单产品的一个功能。
Tips:
1,未使用自定义事件
2,一些细节的逻辑未经过处理,还是存在BUG