Smart_Manager备忘录及各种难点汇总
Smart系列软件全部由React架构完成,React大致流程为:
service:<处理异步请求、调用异步处理>;
export async function query(params) {
return request(`/api/CT/XXXX?${stringify(params)}`);
}
export async function getAllCTOptions(params) {
return request('/api/CT/XXXX', {
method: 'GET',
});
}
export async function submit(params) {
return request(`/api/CT/XXXX/`, {
method: 'POST',
body: {
...params,
},
});
}
effects:call、put、select<获取全局state>;
effects大致写法如下:
effects: {
* fetch({payload}, {call, put}) {
payload = Object.assign({}, payload, {UserID: getUserID()});
let response = yield call(query, payload);
yield put({
type: 'save',
payload: {
list: response.Content,
pagination: {
current:response.Page.PageCurr,
pageSize:response.Page.PageSize,
total:response.Page.ItemTotal,
},
deleteFlag: false
},
});
},
}
//实现页面跳转
effects: {
* Edit({payload}, {call, put}) {
yield put(routerRedux.push(`/settlement/form/${payload.CTID}`));
},
}
reducers:聚合产生当前model的state对象,<纯函数,只返回新的数据>,唯一可以改变state的地方,通过action传入的值与reducers中的值进行对比,产生一个新的state;
reducers大致写法如下:
reducers: {
save(state, action) {
return {
...state,
...action.payload,
};
},
},
action:<js对象>改变state的唯一办法,由dispatch函数调用一个action,改变对应的数据;
const {dispatch} = this.props;
dispatch({
type: 'exchange/fetch',
payload: {Key:e}, //需要传给后台的数据
})
dispatch触发action,reduces描述如何改变state。
components:纯组件,可以复用,import引入所需页面中。
routes:页面一般的业务逻辑可以在这里处理,里面有多个components。
state:表示model的状态数据,通常表现为一个js对象。
1.如何根据后台的数据动态生成不同列的表格?
models中:
if (response.Result) {
//对汇率后台传来的数据进行特殊处理。
let newData = [];
let names = []; //动态列名
response.Content.map((item,index) => {
//获取列名
if(index == 0){
item.RateList.map(n=>names.push(n.Currency));
}
//根据数据,解析成页面所需要的数据格式<nd为固定出现的列数据>
let nd = {
key:index,
TotalMonthlyAccount: item.TotalMonthlyAccount,
MonthMark: `${item.YearMark}-${item.MonthMark.toString().padStart(2, '0')}`,
}
//根据列名生成对应的对象。
names.map(ns=>{
nd[ns] = item.RateList.filter(x => x.Currency == ns)[0].RateValue;
});
newData.push(nd);
});
yield put({
type: 'save',
payload: {
list: newData,
ColumnNames:names,
},
});
} else {
message.error(response.Content);
}
routes中:
CurrencyOpt(){
let {exchange:{ColumnNames}} = this.props;
let CurOption = [];
if(ColumnNames){
CurOption= ColumnNames.map(CurOpt=>{
return(
{
title: CurOpt,
dataIndex: CurOpt,
key: CurOpt,
className: "editable",
render: (text, record) => {
return (
<Input
value={text}
onChange={e => this.handleFieldChange(e, CurOpt, record.key)}
placeholder={CurOpt}
/>);}
})
})
}
return CurOption;}
再在columns中添加如下代码:
...this.CurrencyOpt(),
CurrencyOpt(),
2.如何根据后台的数据动态生成添加一行时的行数据?
index = 0;
// 添加一行<动态数据>
handleAdd = () => {
const newData = this.state.dataSource.map(item => ({...item}));
//动态给定添加行的数据项
const {exchange:{ColumnNames}} = this.props;
let nd = {
key: `NEW_TEMP_ID_${this.index}`, //动态给定key
TotalMonthlyAccount: false,
MonthMark: nowDate,
}
ColumnNames.map(Names=>{
nd[Names] = ``;
})
newData.push(nd);
this.index += 1;
this.setState({dataSource: newData});
};
如何删除掉数组中多余的子数据?
delete newData.key;
newData.key;
componentDidMount方法:<在此方法中用.then然后在其中setState会出现内存泄露的问题>
解决方法:将.then中setState的代码全部放在componentWillReceiveProps方法中!
//componentDidMount方法是在组件已经完全挂载到网页上才会调用被执行,所以可以保证数据的加载
componentDidMount() {
const {dispatch} = this.props;
dispatch({
type: 'project/Edit',
})
}
componentWillReceiveProps方法:<尽量不要在componentWillReceiveProps方法中 dispatch ,否则会死循环!>
componentWillReceiveProps(nextProps) {
const {city: {cityVO}} = nextProps;
if (cityVO) {
this.setState({ID: cityVO.ID});
}
}
//每次监控props,如果是删除之后则需要重新获取数据。
componentWillReceiveProps(nextProps){
const {city} = nextProps;
if(city.deleteFlag){
const {dispatch} = this.props;
dispatch({
type: 'city/fetch',
});
}
}
使用户新添加的汇率行出现在最上面:
const OldData = newData.slice(0,newData.length-1)
const AddData =newData[newData.length-1]
console.log(OldData,AddData)
const NewData = [AddData,...OldData]; //重新赋值给目标Table
解决 Switch 不能重复切换的BUG:
<Col span={6}>
<Form.Item label={fieldLabels.Freezen}>
{getFieldDecorator('Freezen', {
initialValue: userVO.Freezen,
valuePropName: 'checked',
})(<Switch
onChange={(checked) => this.handelChange(checked, 'Freezen')}
/>)}
</Form.Item>
</Col>
通过当前URL判断来设置ID:
const URL = window.location.href.split('form/');
if (URL.length==2){
this.setState({ID:URL[1]})
}else if (URL.length==1){
this.setState({ID:0})
}
判断一个数组中有另一个数组的函数<判断交集是否为空>
const intersection = Array.from(new Set([...Arr1].filter(x => new Set(Arr2).has(x))));
console.log(intersection)
页面的数据刷新会消失?
在componentDidMount方法中将所有的数据放在state中
Smart_Charts备忘录及各种难点汇总
在React中引入echarts和需要用到的图表类型和图表组件:
// 引入 ECharts 主模块
import echarts from 'echarts/lib/echarts';
// 引入需要用到的图表形状
import 'echarts/lib/chart/bar';
import 'echarts/lib/chart/pie';
// 引入提示框和标题组件...
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/title';
import 'echarts/lib/component/legend';
出现报错"dispatch is not a function"?<没有连接model>
解决办法:
@connect(({namespace,loading}) => ({
namespace,
loading: loading.effects['namespace/GetTableData'], //特定为某一个组件添加loading
}))
@Form.create()
*在画 Charts 的函数中定义this<当this.state报错时>:
var self = this; //***重要定义!
目标图表的点击事件:<如柱状图>
TargetChart.on('click', function (recod) {}
.on('click', function (recod) {}
关闭目标图表的点击事件:<通常定义在目标图表的点击事件之前!>
TargetChart.off('click');
.off('click');
给目标图表添加 Loading 状态:
1.先定义需要用到的 State
Success:false, // Chart 数据是否获取成功?<用于判断 Loading 的状态>
const {Success} = self.state;
//region<加载中...>
if (self.state.PRLoading){
TargetChart.showLoading('default',{text:'页面正在拼命加载中...',maskColor:'#a9f0ff',textColor: '#000',});
} else if (self.state.PRLoading ==false){
TargetChart.hideLoading();
}
if (Success) {
self.state.PRLoading = false;
}
//endregion
self.state;
//region<加载中...>
if (self.state.PRLoading){
TargetChart.showLoading('default',{text:'页面正在拼命加载中...',maskColor:'#a9f0ff',textColor: '#000',});
} else if (self.state.PRLoading ==false){
TargetChart.hideLoading();
}
if (Success) {
self.state.PRLoading = false;
}
//endregion
2.在componentWillReceiveProps钩子定义如下 :
componentWillReceiveProps(nextProps) {
const {loadingTable} = nextProps; // ***加载目标图表的effects方法
if (loadingTable == false) {
this.state.Success = true;
}
}
3.然后在需要重置Success的地方重置Success为false并让图表可以 Loading:
//初始化 Loading 为 true
this.state.Success = true;
*如果页面的 State 总是设置慢一步,那就尝试在目标方法/函数下面 dispatch 一下!
*如果 State 会不停的变化,那就用 Props 中对应的数据吧!
多选框的选项可以如下定义:
const XXXOpt = [{value:1,label:'整箱货'},{value:2,label:'拼箱货'},{value:3,label:'散货'}];
动态获取今天是今年中的第几天:
const CurData = Math.ceil(( new Date() - new Date(new Date().getFullYear().toString()))/(24*60*60*1000))+1;
页面第一次获取不到画 Charts 的 DOM,需要在 render 中判断一下,然后在对应方法/函数中画图表,步骤如下:
1.定义 Charts 的容器:
<div id="IO" style={{width: 1080, height: 400}}></div>
2.render 中判断当DOM被加载后,再去画对应的图表:
if(document.getElementById('XX')){
this.DrawChart(echarts.init(document.getElementById('XX')), "XX");
}
3.在对应的方法/函数中定义图表:
DrawChart(TargetChart,fileName) {
var self = this; //***重要定义!
switch (fileName) {
case "XX" :
TargetChart.setOption({...}) //在此定义图表
break;
}
}
4.*如果图表不出来,可以先 dispatch 一下!
*判断一个数组中有另一个数组的函数<判断交集是否为空>
const Array1 = [1,2,3];
const Array2= [2,3,4];
//*判断一个数组中有另一个数组的函数<判断交集是否为空>
const intersection = Array.from(new Set([...Array1].filter(x => new Set(Array2).has(x))));
|