睡觉果然有用,睡了觉又想到更好的思路,这里就不用Promise了,代码看着不简洁,直接用EventBus在内部将需要的数据派发出来,然后在业务组件里面进行启动绘制和提交请求的解耦,这样一下子做到了需求拆解,逻辑变得简单,而且丰富了UI跟高大上了有木有,哎,有木有?
大伙好,我又带来干货啦,今天在做交互时有个问题困扰了我许久,先说应用场景:
用户对影像进行绘制区域栅格统计查询,统计出栅格的区间占比,最后根据数据生成带图例的饼状图,像这样:
在组件化开发的时代,讲究功能组件化、组件功能单一化,展示组件逻辑要完全和地图组件分离开,不能出现展示组件中引入ol库的low代码。大家用过ol的都清楚,ol的Draw绘制监听是回调,例如:
draw.on("drawend", (DrawEvent) => {
DrawEvent.feature.getGeometry().flatCoordinates);//绘制坐标串
});
那么这种回调我们是没办法控制的,在这里就特别容易出现功能耦合(部分绘制无关的逻辑必须写在回调),破坏了功能单一性。接下来说说我的思路和看法,如果有更好思路的可以讨论一下,我也希望写出更好的逻辑。
1.这里地图组件职责是统管所有和地图相关的操作,我这边列举一些:
只包含一些地图、图层、绘制、地位等等地理操作
2.非地图,也叫业务功能,这里以栅格统计展示图表组件为例
这里面只写栅格统计的逻辑
有vue开发经验的朋友都知道这个通信是必不可少的,但我这里要提一点的是,在WebGIS开发过程中,异步操作占80%,这里如果你是使用EventBus进行组件对象的传递的话,注意使用位置,一是EventBus.$emit派发要放在初始化后面,EventBus.$on接收要放在beforeMount
return new Promise((resolve) => {
let drawEvent = draw.on(
"drawend",
(DrawEvent) => {
// 拿到extent拼接成左上右下查询格式
let cord = DrawEvent.feature.getGeometry().extent_;
let bounds = {
leftBottom: {
x: cord[0],
y: cord[1],
},
rightTop: {
x: cord[2],
y: cord[3],
},
};
resolve(bounds);
}
);
console.log(drawEvent);
});
在函数中用Promise进行包裹,再resolve出你需要操作的参数,我这边是操作边界bound
前三步都比较顺通,相信也是许多朋友走过的流程,但是如果这是你需要点击绘制按钮,需要每次绘制区域都刷新结果,那基本没戏,因为本次调用以及结束,绘制信息以及死在map组件的函数襁褓里面喽!
这里就可以先在业务组件中把刚刚的resolve里面的值用async/await先取到,然后保存到当前组件的data中,最后在watch中监听数据,这里直接对函数进行调用,就可以做到实时导出draw.on()回调里面的数据啦。
watch:{
RecQueryBounds:{
handler(newValue, oldValue) {
this.RecQuery()
},
// 矩形统计
async RecQuery() {
// 取点 左下 右上 走extent就行
// 也支持多边界查询
this.RecQueryBounds = await this.MapCom.DrawGeometry();
console.log(this.RecQueryBounds);
// 拿到数据去更新
await this.RasterQueryApi(this.RecQueryBounds);
this.RasterStatistics();
},
来的都是朋友,上述的分有错误还希望各位朋友指出,有更好的思路也可以教一下我,最后有疑问可以留言或者私信讨论,今天的分析就到这里啦,睡大觉去。