Salesforce LWC学习(六) @salesforce & lightning/ui*Api Reference
上一篇中我们在demo中使用了很多的 @salesforce 以及 lightning/ui*Api的方法,但是很多没有细节的展开。其实LWC中针对这些module提供了很多好用的方法,下面对这两种进行详细介绍。
一. @Salesforce
@salesforce模块封装了很多的方法,用于在运行时添加相关的功能。主要方法及使用如下。
1. @salesforce/apex : 此方法用于引入apex的方法,这里的方法包括自定义的方法以及标准的预置的方法,具体操作如下。
1)引入自定义apex类的方法:我们在项目中和后台apex代码交互,首先需要做的就是使用此标签引入需要用到的类的方法。
import apexMethod from '@salesforce/apex/Namespace.Classname.apexMethod';
@wire(apexMethod, { apexMethodParams })
propertyOrFunction;
针对此函数相关的变量在上一篇有细节描述,除了引入自定义apex方法以外,还有其他的一些封装的标准的方法。
2)getSObjectValue(sobject, fieldApiName):此方法用与从一个object中获取指定的field的值。这个object是从apex中搜索出来的。
此方法两个参数,sobject代表从后台apex中搜索出来的数据,fieldApiName为想要查询字段值的API name。fieldApiName可以是String类型的api name也可以通过@salesforce/schema方式引入进来。我们在搜索时可能获取父层数据,比如搜索opportunity数据时需要获取其对应的account的owner信息,此种父查询展示的最大深度为5层,比如Opportunity.Account.CreatedBy.LastModifiedBy.Name。
头部需要引用:import { getSObjectValue } from '@salesforce/apex';然后调用此方法即可。
getSObjectValueDemo.html
<template>
{accountOwnerName}
</template>
getSObjectValueDemo.js:调用findOpportunity后台方法,此方法搜索了Opportunity的Account.Owner.Name,我们可以使用getSObjectValue获取其字段结果。
import { LightningElement, wire } from 'lwc';
import findOpportunity from '@salesforce/apex/OpportunityController.findOpportunity';
import { getSObjectValue } from '@salesforce/apex';
import OPPORTUNITY_ACCOUNT_OWNER_NAME from '@salesforce/schema/Opportunity.Account.Owner.Name';
export default class GetSObjectValueDemo extends LightningElement { @wire(findOpportunity,{searchKey:'test'})
opportunityList; get accountOwnerName() {
if(this.opportunityList.data !== undefined) {
const opportunity = this.opportunityList.data[0];
return getSObjectValue(opportunity,OPPORTUNITY_ACCOUNT_OWNER_NAME);
}
return '';
}
}
OpportunityController.cls
public with sharing class OpportunityController {
@AuraEnabled(cacheable=true)
public static List<Opportunity> findOpportunity(String searchKey){
String key = '%' + searchKey + '%';
return [SELECT Id,Account.Owner.Name
FROM Opportunity
WHERE Name like :key
ORDER BY LastModifiedDate DESC
limit 1];
}
}
3)refreshApex(wiredProperty):用于使用wire注解情况下针对缓存变量的刷新,此方法只针对缓存变量,其他情况无法使用。
头部需要引用:import { refreshApex } from '@salesforce/apex';
详情用法可以查看上一篇。
4)@salesforce/apexContinuation:主要用于长时间运行的callout,此功能后期会单独描述。
5)@salesforce/label:用于引入custom label。
头部需要引入:import labelName from '@salesforce/label/labelReference'
其中:
labelName为我们起的名字,后期js以及前台html中用到此custom label的地方需要使用此名字作为引用
labelReference为在我们org中声明的custom label的label name。引入时需要使用namespace.labelName格式进行引用,如果不是manage package,默认的namespace为c。
因为我们在js中可能获取多个custom label,所以我们可以封装在一个label的变量中,通过label.labelName方式获取。custom label我们声明的时候会有两种形式,一种是正常的,另外一种是可以使用{0}{1}这种format的操作的label。针对classic以及lightning aura我们可以很轻易的对format的label进行处理,遗憾的是针对lwc并没有直接的方式去处理,我们可以使用正则表达式进行函数处理。
stringUtils.js:用于解析字符串中使用{}处理的占位符。
const formatString = (stringForFormat,params) => {
let str = stringForFormat;
for (let i = 0; i < params.length; i++) {
let re = new RegExp('\\{' + i + '\\}', 'gm');
str = str.replace(re, params[i]);
}
return str;
};
export {formatString};
getCustomLabelDemo.js:引入方法,针对包含format的字符串进行处理。
import { LightningElement } from 'lwc';
import sampleLabel from '@salesforce/label/c.sample_label';
import sampleLabelWithParam from '@salesforce/label/c.sample_label_with_param';
import {formatString} from 'c/stringUtils';
export default class GetCustomLabelDemo extends LightningElement { get formatedSampleLabelWithParam() {
let paramList = new Array();
paramList.push('xx');
return formatString(sampleLabelWithParam,paramList);
} label = {
sampleLabel
};
}
getCustomLabelDemo.html:展示两个custom label
<template>
{label.sampleLabel}
<br/>
{formatedSampleLabelWithParam}
</template>
显示结果:
6)@salesforce/resourceUrl:引入static resource。头部根据当前的静态资源是否在managed package中有两种引用的方式:
import resourceName from '@salesforce/resourceUrl/resourceReference';
import myResource from '@salesforce/resourceUrl/namespace__resourceReference';
demo如下:
useStaticResourceDemo.js:引入static resource,在sample目录下有一个sample.png图片,前台展示此图片
import { LightningElement } from 'lwc';
import sampleResource from '@salesforce/resourceUrl/lwc_sample';
export default class UseStaticResourceDemo extends LightningElement {
pictureSampleURL = sampleResource + '/sample/sample.png';
}
useStaticResourceDemo.html:展示此图片
<template>
<img src={pictureSampleURL}/>
</template>
效果展示:
7)@salesforce/schema:引入object以及field的引用。当我们使用LDS或者wire service获取字段的引用时,官方建议我们使用此种方式而不是字符串方式,详细使用操作可以查看上一篇博客。
8)@salesforce/user:获取当前user的信息。通过此引用可以获取当前user的id 以及当前user是否是一个community guest user。我们通过
import property from '@salesforce/user/property';来引用,property有两个值:Id / isGuest.下面是一个关于user信息的获取的demo。
getUserInfoDemo.js
import { LightningElement } from 'lwc';
import Id from '@salesforce/user/Id';
import isGuest from '@salesforce/user/isGuest';
export default class GetUserInfoDemo extends LightningElement {
userId = Id;
isGuestUser = isGuest;
}
getUserInfoDemo.html
<template>
current user Id : {userId}<br/>
current user is Guest {isGuestUser}
</template>
以上的内容为@salesforce模块封装的主要方法,详情还请自行查看文档。接下来的几部分我们讲的主要是 lightning/ui*Api部分的wire adapter,其主要是为了扩充LDS标准以外的增强方法。LWC针对数据的操作以及解析如下图所示。LWC wire adapter以及LDS转成的都是User Interface API中的内容,所以如果想更好的了解各个wire adapter的使用以及返回类型的详情还请查看User Interface API。下载地址:https://resources.docs.salesforce.com/220/latest/en-us/sfdc/pdf/api_ui.pdf
二. lightning/uiListApi
此模块主要用于针对一个list view获取数据以及metadata。我们针对某个对象数据创建列表视图时,会进行相关的filter,展示某些固定的列,展示多少数据等操作。使用lightning/uiListApi模块我们可以通过object的api name等信息便可以获取到指定的list view的数据。需要注意一点的是,此模块以及模块中的方法目前是beta功能。
1) 使用 object 的api name以及 list view的api name去获取数据;
import { getListUi } from 'lightning/uiListApi';
@wire(getListUi, { objectApiName: objName, listViewApiName: listViewName })
propertyOrFunction;
其中objName代表想要获取哪个表的数据,取得是表的api name
listViewName取得是当前表的哪个list view的数据,取得是 list view的api name
2)使用list view的id 获取数据;
import { getListUi } from 'lightning/uiListApi';
@wire(getListUi, { listViewId:listViewId})
propertyOrFunction;
3)使用object 的api name以及MRU(Most Recently Used)去获取数据.我们在每个表的list view中都有一个rencent view的视图,这个是标准的一个视图,LWC针对此视图有专门的取法。
import { getListUi, MRU } from 'lightning/uiListApi';
@wire(getListUi, { objectApiName: objectName, listViewApiName: MRU })
propertyOrFunction;
除了上述的必传的参数以外,此适配器方法还提供了其他的可选参数,比如pageSize等。
import { LightningElement, wire,track } from 'lwc';
import {getListUi} from 'lightning/uiListApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
export default class GetListUIDemo extends LightningElement {
@track error;
@track accountList;
@wire(getListUi,{objectApiName:ACCOUNT_OBJECT,listViewApiName:'AllAccounts',pageSize:100})
wiredAccountList({error,data}) {
if(data) {
this.accountList = data.records.records;
this.error = undefined;
} else if(error) {
this.error = error;
this.accountList = undefined;
}
}
}
getListUIDemo.html
<template>
<lightning-card title="get list ui demo" icon-name="standard:action_list_component"> <table class="slds-table slds-table_cell-buffer slds-table_bordered">
<thead>
<tr class="slds-line-height_reset">
<th class="" scope="col">
<div class="slds-truncate">Account Id</div>
</th>
<th class="" scope="col">
<div class="slds-truncate">Account Name</div>
</th>
<th class="" scope="col">
<div class="slds-truncate">Type</div>
</th>
<th class="" scope="col">
<div class="slds-truncate">Phone</div>
</th>
</tr>
</thead>
<tbody>
<template if:true={accountList}>
<template for:each={accountList} for:item="account">
<tr key={account.id}>
<td>{account.id}</td>
<td> {account.fields.Name.value}</td>
<td> {account.fields.Type.value}</td>
<td> {account.fields.Phone.value}</td>
</tr>
</template>
</template>
<template if:false={accountList}>
List View is not contains any data
</template>
</tbody>
</table>
</lightning-card>
</template>
结果展示:
三. lightning/uiObjectInfoApi
此模块的适配器方法用于获取object的metadata以及picklist的value。
1. getObjectInfo:使用wire adapter针对指定的object获取相关的metadata。response包括描述fields/ child relationships / record type/theme metadata信息。下图可以看到我们demo中用到的获取Account的getObjectInfo的结构。我们对于apex中的Schema有了解情况下,可以理解成此适配器相当于DescribeSObjectResult以及相关的方法用来获取相关的metadata信息。demo中我们会演示获取某个字段的label信息,感兴趣的可以自行研究。
getSObjectInfoDemo.js:获取Account表中的AccountSource的label值
import { LightningElement,wire } from 'lwc';
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
export default class GetObjectInfoDemo extends LightningElement {
@wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
accountInfo; get recordInfo() {
if(this.accountInfo.data !== undefined) {
return this.accountInfo.data.fields.AccountSource.label;
}
return '';
}
}
getSObjectInfoDemo.html:展示AccountSource的label值
<template>
{recordInfo}
</template>
2. getPicklistValues:使用此wire adapter获取某个 picklist类型字段的picklist value。我们接触apex知道,picklist 字段获取可以使用两种方式,基于record type方式获取某个record type的picklist values以及获取picklist类型字段的所有的values。此wire adapter为通过record type获取values。此wire adapter需要传两个参数,第一个参数是object的某个record type id,第二个参数是想要获取的picklist类型的字段API名称。
@wire(getPicklistValues, { recordTypeId: recordTypeId, fieldApiName: fieldApiName })
propertyOrFunction;
其中,recordTypeId为我们想要操作的指定record type的ID。我们可以根据getObjectInfo 或者getRecordUi这两个wire adapter获取。此变量为必填字段,我们如果想变量改变getPicklistValues动态改变,我们可以使用'$'符号去封装此变量;fieldApiName为想要查询字段的API name,这里推荐使用@salesforce/schame去获取field api的reference。返回的类型有两种,变量或者是方法,变量封装data和error两个子变量,使用方法我们可以将这两个作为参数进行展示。详见上篇的propertyOrFunction的使用。
下面的demo我们来获取account中的industry的picklist values。
getObjectInfoDemo.js:首先我们先使用getObjectInfo获取Account的schema信息,然后通过getPicklistValues获取picklist信息,这里使用$作为动态传参,保证当objectInfo变量先装载,装载以后执行getPicklistValues。
import { LightningElement,wire} from 'lwc';
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import {getPicklistValues} from 'lightning/uiObjectInfoApi';
import ACCOUNT_INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';
export default class GetObjectInfoDemo extends LightningElement { @wire(getObjectInfo,{objectApiName:ACCOUNT_OBJECT})
objectInfo; @wire(getPicklistValues,{ recordTypeId: '$objectInfo.data.defaultRecordTypeId', fieldApiName: ACCOUNT_INDUSTRY_FIELD })
industryList;
}
getObjectInfoDemo.html:使用for:each进行遍历industry list,使用select option进行展示数据。
<template>
<lightning-card title="Industry List ">
<template if:true={industryList.data}>
<div class="slds-m-around_medium">
<select>
<template for:each={industryList.data.values} for:item="item">
<option key={item.value}>{item.label}</option>
</template>
</select>
</div>
</template>
</lightning-card>
</template>
效果如下:
3. getPicklistValuesByRecordType:此方法用于获取某个对象,某个record type的所有的picklist 的values,这些picklist values封装在一个map中。
@wire(getPicklistValuesByRecordType, { objectApiName: objectName, recordTypeId: recordTypeId })
propertyOrFunction
其中objectName为想要获取的object的所有的picklist values的object api name,此字段必填,推荐使用@salesforce/schema获取,recordTypeId也是必填字段,获取方式同上一个wire adapter。我们通过一个例子更好的理解。
getPicklistValuesByRecordTypeDemo.js:用来获取record type名称为 Test Record Type的所有的picklist values信息。
import { LightningElement, wire,track } from 'lwc';
import {getObjectInfo} from 'lightning/uiObjectInfoApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import {getPicklistValuesByRecordType} from 'lightning/uiObjectInfoApi';
export default class GetPicklistValuesByRecordTypeDemo extends LightningElement {
@track recordTypeId = '';
@wire(getObjectInfo,{objectApiName:ACCOUNT_OBJECT})
getObjectInfo({data,error}) {
if(data) {
const allRecordTypeInfos = data.recordTypeInfos;
// eslint-disable-next-line no-console
console.log(JSON.stringify(allRecordTypeInfos));
this.recordTypeId = Object.keys(allRecordTypeInfos).find(rti => allRecordTypeInfos[rti].name === 'Test Record Type');
} else if(error) {
//TODO
}
} @wire(getPicklistValuesByRecordType,{ objectApiName: ACCOUNT_OBJECT, recordTypeId: '$recordTypeId'})
picklistValues; get demo() {
// eslint-disable-next-line no-console
console.log(JSON.stringify(this.picklistValues));
return this.recordTypeId;
} }
这里我们使用getObjectInfo获取所有的record type,打印出来的all record type 信息如下所示,我们可以看出来,它的结果集是一个Map,key是record type id,value封装了相关的细节信息,我们使用Object.key.find来获取指定名称的record type id信息。此使用方法是javascript的遍历map的使用,感兴趣的可以自行查看。
通过record type id我们使用getPicklistValuesByRecordType获取所有的picklist valus,格式的层级模式如下图所示。
获取到层级模式以后,我们对程序进行一下增强,获取所有的AccountSource的picklist values。
在上面的js方法中添加此方法。
get accountSourcePicklistValues() {
// eslint-disable-next-line no-console
console.log(JSON.stringify(this.picklistValues));
if(this.picklistValues !== undefined && this.picklistValues.data !== undefined) {
return this.picklistValues.data.picklistFieldValues.AccountSource.values;
}
return '';
}
getPicklistValuesByRecordTypeDemo.html
<template>
<lightning-card title="Account Source List ">
<template if:true={accountSourcePicklistValues}>
<div class="slds-m-around_medium">
<select>
<template for:each={accountSourcePicklistValues} for:item="item">
<option key={item.value}>{item.label}</option>
</template>
</select>
</div>
</template>
</lightning-card>
</template>
效果展示:
三. lightning/uiRecordApi
此模块中的wire adapter主要用于进行数据的CRUD。下面列举几个主要的方法,其他的方法还请自行查看文档。
1. getRecord:用于通过record id获取此id对应的record 信息,详情用法以及参数介绍参看上一篇,有详细描述。
@wire(getRecord, { recordId: string, fields: string[], optionalFields?: string[])
propertyOrFunction @wire(getRecord, { recordId: string, layoutTypes: string[],
modes?: string[], optionalFields?: string[])
propertyOrFunction
2. getRecordUi:使用此wire adapter可以针对一条或者多条记录获取其对应的page layout,metadata以及在UI上面的数据信息。我们上面也讲过如果想要获取record type id也可以使用此wire adapter。
@wire(getRecordUi, { recordIds: string, layoutTypes: string,
modes: string, optionalFields?: string[] })
propertyOrFunction; @wire(getRecordUi, { recordIds: string[], layoutTypes: string[],
modes: string[], optionalFields?: string[] })
propertyOrFunction;
可以看到参数和getRecord很相似,返回的对象为Record UI对象以及error两个。我们可以在User Interface中封装的Record UI查看返回的结构以及如何获取需要的内容信息。返回的层级结构以及信息如下图所示,我们只需要根据不同的取值需要获取不同的值即可。
3. getFieldValue(record,field):此方法用于获取记录中指定field API对应的value。需要注意的是,他获取的永远是API value。此方法的demo在上一篇有介绍,可以查看上一篇。
4. getFieldDisplayValue(record,field):此方法相对上一个方法的区别为此方法获取的是展示的value。比如一个picklist字段,我们有国际化操作,针对picklist value可能是英文,但是我们对其中文进行translation,那么针对语言为中文的客户,getFieldValue获取的是picklist 的value,即英文的值,getFieldDisplayValue获取的是中文的值。
getFieldDisplayValueDemo.js:此方法用于获取Account Source的value以及display value
import { LightningElement,api, wire } from 'lwc';
import {getRecord} from 'lightning/uiRecordApi';
import {getFieldValue} from 'lightning/uiRecordApi';
import {getFieldDisplayValue} from 'lightning/uiRecordApi';
import ACCOUNT_ACCOUNT_SOURCE from '@salesforce/schema/Account.AccountSource';
export default class GetFieldDisplayValueDemo extends LightningElement {
@api recordId; @wire(getRecord,{recordId:'$recordId',fields:[ACCOUNT_ACCOUNT_SOURCE]})
account; get accountSourceValue() {
if(this.account.data !== undefined) {
return getFieldValue(this.account.data,ACCOUNT_ACCOUNT_SOURCE);
}
return '';
} get accountSourceDisplayValue() {
if(this.account.data !== undefined) {
return getFieldDisplayValue(this.account.data,ACCOUNT_ACCOUNT_SOURCE);
}
return '';
}
}
getFieldDisplayValueDemo.html
<template>
value : {accountSourceValue}<br/>
label : {accountSourceDisplayValue}
</template>
效果展示
5. createRecord(recordInput: Record):此方法用于创建一条记录,其中Record我们需要使用wire service提供的generateRecordInputForCreate(record,objectInfo) 这个wire adapter去实例化一个Record。返回类型为一个Promise,即当前的这个Record,包括当前记录的page layout中的信息。使用createRecord以及使用updateRecord这两个方法前需要先思考是否可以使用lightning-record-form以及lightning-record-edit-form去搞定。搞定不了情况下在使用wire adapter。此wire adapter官方提供了简单的demo,查看此链接便可以更好的了解此wire adapter:https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.data_salesforce_write
6. updateRecord(recordInput, clientOptions):同上方法,用于编辑一条记录,参数中的recordInput需要使用wire service提供的generateRecordInputForUpdate(record,objectInfo)去搞定,还是和上面的一样,如果实在搞定不了在使用此方法,否则尽量别用。
7. deleteRecord(recordId):用于删除一条记录,传入当前的record id即可实现删除操作。方法为void类型,没有返回内容。
总结:篇中简单的整理了一些针对@salesforce 以及 lightning/record*Api模块的方法,细节的方法描述还请自行查看官方文档以及User Interface API。其实除了这两个module,LWC还提供了很多好用的module,比如lightning/platformShowToastEvent用于展示toast信息等等,还要靠小伙伴自己挖掘。
另外需要注意的一点的是,针对wire service的这些wire adapter,如果可以使用lightning:record-form相关的搞定,能不用尽量不用,标准功能搞定不了在考虑使用。篇中有错误地方欢迎指出,有不懂的欢迎提问。
Salesforce LWC学习(六) @salesforce & lightning/ui*Api Reference的更多相关文章
- Salesforce LWC学习(一)Salesforce DX配置
LWC: Create a Salesforce DX Project and Lightning Web Component:https://www.youtube.com/watch?v=p268 ...
- Salesforce LWC学习(二十三) Lightning Message Service 浅谈
本篇参考: https://trailhead.salesforce.com/content/learn/superbadges/superbadge_lwc_specialist https://d ...
- Salesforce LWC学习(三十) lwc superbadge项目实现
本篇参考:https://trailhead.salesforce.com/content/learn/superbadges/superbadge_lwc_specialist 我们做lwc的学习时 ...
- Salesforce LWC学习(五) LDS & Wire Service 实现和后台数据交互 & meta xml配置
之前的几节都是基于前台变量进行相关的操作和学习,我们在项目中不可避免的需要获取数据以及进行DML操作.之前的内容中也有提到wire注解,今天就详细的介绍一下对数据进行查询以及DML操作以及Wire S ...
- Salesforce LWC学习(三十九) lwc下quick action的recordId的问题和解决方案
本篇参考: https://developer.salesforce.com/docs/component-library/bundle/force:hasRecordId/documentation ...
- Salesforce LWC学习(四十) dynamic interaction 浅入浅出
本篇参考: Configure a Component for Dynamic Interactions in the Lightning App Builder - Salesforce Light ...
- Salesforce LWC学习(十七) 前端知识之 onclick & onblur & onmousedown
在Salesforce LWC学习(八) Look Up组件实现篇中,我们实现了公用的lookup组件,使用的过程中,会发现当我们输入内容以后,搜索出来的列表便无法被清空. 针对此种情况我们打算优化一 ...
- Salesforce LWC学习(二十九) getRecordNotifyChange(LDS拓展增强篇)
本篇参考: https://developer.salesforce.com/docs/component-library/documentation/en/lwc/data_ui_api https ...
- Salesforce LWC学习(三十五) 使用 REST API实现不写Apex的批量创建/更新数据
本篇参考: https://developer.salesforce.com/docs/atlas.en-us.224.0.api_rest.meta/api_rest/resources_compo ...
随机推荐
- 优雅的对象转换解决方案-MapStruct使用进阶(二)
在前面, 介绍了 MapStruct 及其入门. 本文则是进一步的进阶. 在 MapStruct 生成对应的实现类的时候, 有如下的几个情景. 1 属性名称相同,则进行转化 在实现类的时候, 如果属性 ...
- 数据结构之堆栈C++版
/* 堆栈本身就是一种线性数据结构,说白了他与容器线性表是一种数据类型,不要认为他多高大上. 实时上他还没有线性表复杂,下面简单的实现一下堆栈. 事实上整个核心操作都是在操作指向堆栈的顶部元素的指针 ...
- C#并发实战Parallel.ForEach使用
前言:最近给客户开发一个伙食费计算系统,大概需要计算2000个人的伙食.需求是按照员工的预定报餐计划对消费记录进行检查,如有未报餐有刷卡或者有报餐没刷卡的要进行一定的金额扣减等一系列规则.一开始我的想 ...
- Caffeine Cache-高性能Java本地缓存组件
前面刚说到Guava Cache,他的优点是封装了get,put操作:提供线程安全的缓存操作:提供过期策略:提供回收策略:缓存监控.当缓存的数据超过最大值时,使用LRU算法替换.这一篇我们将要谈到一个 ...
- 本地(任意)时间戳转化(转换)标准时间格式 js(eg:2019-05-07 17:49:12)
<script> function getLocalTime(timestamp) { // 如果以秒为单位 // var dateObj = new Date(timestamp * 1 ...
- 洛谷 P2157 [SDOI2009]学校食堂
题意简述 每个人有一个口味,食堂每次只能为一个人做菜 做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为a 异或 b 每个人都有一个容忍度,最多允许紧 ...
- tomcat9 web manager的配置使用
本地链接tomcat web manager服务时,只需修改tomcat/conf/tomcat-user.xml文件,如图所示: 远程链接tomcat web manager服务时,需要在tomca ...
- 小白学Python(4)——用Python创建PPT
python-pptx是一个用于创建和更新PowerPoint(.pptx)文件的Python库. 典型的用途是从数据库内容生成自定义的PowerPoint演示文稿,可通过单击Web应用程序中的链接进 ...
- Spark流式编程介绍 - 编程模型
来源Spark官方文档 http://spark.apache.org/docs/latest/structured-streaming-programming-guide.html#programm ...
- python学习笔记(6)--面向对象学习
本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引言 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做(人狗大战)的游戏,你就思 ...