Smart 备忘录及各种难点汇总

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 17:15   1727   0

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))));

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP