有一个react的历史项目需要重构,都是class组件,多个组件间有些复用方法,通过在componentDidMount中,对this进行utils方法注入,注入之后类的实例就拥有了utils中的方法,但是放到TS的环境,会报错类型上不存在类上不存在注入的属性,应该怎么处理呢?
markPoints
关键代码如下所示:
类组件
import {
DataMark,
} from '../widgets/utils';
componentDidMount() {
if (this._echarts) {
const echartsIns = this._echarts.getEchartsInstance();
// 初始化标注
DataMark.init(this, echartsIns);
}
}
componentDidUpdate(prevProps, prevState, snapshot) {
//以下markPoints方法是通过utils注入进来的
//js环境运行没有问题,在TS下会报错,提示没有markPoints属性
//如何在TS中声明这些属性呢?
this.markPoints(
getValue(setting, 'custom.dataMark', []),
getValue(option, 'series'),
getValue(setting, 'custom.dataLabel', false)
);();
}
utils中DataMark的内容如下:
const fns = {
markPoints(points: any[], series: any[], showDataLabel: any) {
if (points.length > 0) {
series.forEach(
(
s: {
data: any[];
markPoint: {
symbol: string;
symbolSize: number;
symbolOffset: (string | number)[];
label: { show: boolean };
itemStyle: { color: string };
zlevel: number;
data: any;
};
},
index: any
) => {
const markPoints = points.filter(
(mark: {
seriesIndex: any;
valueName: any;
value: any;
category: any;
}) =>
mark.seriesIndex === index &&
s.data.some(
(item: { valueName: any; value: any; category: any }) =>
item &&
item.valueName === mark.valueName &&
item.value === mark.value &&
item.category === mark.category
)
);
if (markPoints.length > 0) {
s.markPoint = {
symbol: DATA_MARK_SYMBOL,
symbolSize: 16,
symbolOffset: showDataLabel ? [0, '-200%'] : [0, -10],
label: {
show: false,
},
itemStyle: {
color: '#4159F7',
},
zlevel: 2,
data: markPoints.map(
(markPoint: {
id: any;
category: { toString: () => any };
value: any;
content: any;
}) => ({
name: markPoint.id,
coord: [markPoint.category.toString(), markPoint.value],
category: markPoint.category,
value: markPoint.value,
content: markPoint.content,
})
),
};
}
}
);
}
},
};
function onSelect(this: any, params) {
const dataMarkStatus = _.get(this.props, 'widgetDesign.dataMarkStatus');
if (
dataMarkStatus === DATA_MARK_STATUS.SELECT &&
params.componentType !== 'markPoint'
) {
this.props.dispatch({
type: 'widgetDesign/updateState',
payload: {
dataMarkStatus: DATA_MARK_STATUS.ADD,
dataMarkData: params,
},
});
}
}
function onView(this: any, params) {
const dataMarkStatus = _.get(this.props, 'widgetDesign.dataMarkStatus');
if (
params.componentType === 'markPoint' &&
dataMarkStatus !== DATA_MARK_STATUS.SELECT
) {
// 设置显示位置
let style = {};
if (params.event) {
const { target } = params.event.event;
const { top, left } = target.getBoundingClientRect();
const { offsetX, offsetY } = params.event;
style = {
position: 'absolute',
top: top + offsetY - 50,
left: left + offsetX - 75,
};
}
const _container = document.createElement('div');
document.body.appendChild(_container);
ReactDOM.render(
<Modal
visible
width={150}
onCancel={() => {
ReactDOM.unmountComponentAtNode(_container);
document.body.removeChild(_container);
}}
footer={null}
closable={false}
style={style}
maskStyle={{ backgroundColor: 'transparent' }}
className={styles.dataMarkView}
>
{params.data.content}
</Modal>,
_container
);
}
}
const dataMark = {
init(
context: any,
echartsIns: {
on: (
arg0: string,
arg1: { (params: any): void; (params: any): void }
) => void;
}
) {
const { isEdit } = context.props;
// 编辑标注
if (isEdit) {
echartsIns.on('click', onSelect.bind(context));
}
// 查看标注
echartsIns.on('click', onView.bind(context));
// 注入方法
Object.keys(fns).forEach((key) => {
context[key] = fns[key];
});
},
};
export default dataMark;