uniapp+arcgis系列(三):逻辑层和视图层RenderJS之间的相互通信
github地址:点击此处跳转
uniapp-arcgis系列目录:
uniapp+arcgis系列(一): uniapp引入ArcGis for JS 4.x,并加载地图服务、显示地图,去除边框、水印和缩放按钮
uniapp+arcgis系列(二): 在外部调用arcgis api,地图加载完成事件
uniapp+arcgis系列(三):逻辑层和视图层RenderJS之间的相互通信
uniapp+arcgis系列(四): 获取wgs84坐标、获取火星坐标GCJ-02以及当前位置信息的省市街道地址名称、poi兴趣点,点击地图画点和轨迹
由于地图是加载在视图层的,所以掌握视图层和逻辑层双向通信的方法是必须的。
一、视图层RenderJS主动和逻辑层通信
这里相对简单,需要在renderJS中调逻辑层的方法,通过特定的方式直接调就行了。
首先在逻辑层中定义一个给视图层调用的方法:
<!-- 逻辑层代码 -->
<script>
export default {
data() {
return {}
},
methods: {
/**
* 给renderJS调用的方法
*/
methodForRenderJs:function(val){
console.log("我是逻辑层,被视图层调用了,并且收到参数:");
console.log(val);
},
}
}
</script>
然后在业务层调用这个方法:
this.$ownerInstance.callMethod('methodForRenderJs',{val1:"参数1",val2:"参数2"});
控制台输出:
二、逻辑层主动和视图层RenderJS通信
实话实说这个有点抽象。
因为逻辑层是不能直接主动通信视图层,只能向视图层添加一个属性,并且在视图层为这个属性绑定一个变化事件,逻辑层通过对这个属性值动手动脚,来达到向视图层传递数据、调用视图层的方法的效果。
所以划重点:逻辑层离了view是没办法和视图层通信的!!!离开了这个页面view作废!!!通信作废!!!
如果离开当前页面以后,仍然需要arcgis在后台一直持续不停地处理数据,用这种方法是行不通的!!!放弃arcgis罢。
简单概括下:
在视图层的view,给view绑定一个属性msg,再绑定一个msg的变化事件。
像这样:
<view :msg="valueChangeSign" :change:msg="myMapViews.valueChange" type="default"></view>
- valueChangeSign 是定义在逻辑层中的data{return{}}里面的属性
- myMapViews是逻辑层的module
<script module="myMapViews" lang="renderjs">
- valueChange 是定义在视图层的method里面的方法
valueChange(newVal, oldVal, ownerVm, vm) {
console.log("我是新数据....");
console.log(newVal);
console.log("我是旧数据....");
console.log(oldVal);
},
valueChangeSign的值改变,会触发valueChange这个事件,并且该事件可以拿到新的值、旧的值。
可以通过在逻辑层中操作valueChangeSign来触发这个事件并且传递数据。
如果只是想单纯的触发事件,可以将valueChangeSign的值设置为系统当前时间的毫秒数,确保它一定会变化。
this.valueChangeSign = new Date().getTime();
如果不仅需要触发事件,还需要传递一个复杂的对象作为参数,就是达到vue中的深度监听的效果,可以写成这样:
var map = new Map();
map["name"] = "逻辑层";
map["value"] = "传递值";
this.valueChangeSign = [new Date().getTime(), map];
valueChange(newVal, oldVal, ownerVm, vm) {
var map = newVal[1];
},
传递一个数组,把数组的0设置为系统时间毫秒数,这样既可以传递复杂对象,也能保证事件触发。
控制台输出:
来看一下效果:
这里我是添加了一个定时器来改变值。
三、完整代码
<template>
<view>
<view :msg="valueChangeSign" :change:msg="myMapViews.valueChange" type="default"></view>
<template>
<view style="width: 350px;height: 600px;" id="myMapView" />
</template>
</view>
</template>
<!-- 逻辑层代码 -->
<script>
export default {
data() {
return {
valueChangeSign:"", // 调用视图层方法的信号
}
},
methods: {
/**
* 给renderJS调用的方法
*/
methodForRenderJs:function(val){
console.log("我是逻辑层,被视图层调用了,并且收到参数:");
console.log(val);
},
},
onShow() {
let this_ = this;
setInterval(function(){
var map = new Map();
map["name"] = "逻辑层";
map["value"] = "传递值";
this_.valueChangeSign = [new Date().getTime(),map];
},5000);
}
}
</script>
<!-- RenderJS视图层代码 -->
<script module="myMapViews" lang="renderjs">
import {
loadModules
} from 'esri-loader'
export default {
name: 'myMapView',
data() {
return {
myMapObject: {}, // 对象,存储关于地图的图层、方法、属性等
}
},
methods: {
createMapView() {
var this_ = this;
return new Promise(function(resolve){
const options = {
url: 'https://js.arcgis.com/4.14/init.js',
css: 'https://js.arcgis.com/4.14/esri/themes/light/main.css'
};
loadModules([
"esri/Map",
"esri/views/MapView",
"esri/Basemap",
"esri/layers/Layer",
"esri/layers/TileLayer",
], options).then(([Map, MapView, Basemap, Layer, TileLayer]) => {
// 地图的底图
var url =
"http://cache1.arcgisonline.cn/arcgis/rest/services/ChinaOnlineCommunity_Mobile/MapServer";
var basemaplayer = new TileLayer({
url: url,
visible: true,
});
// 地图对象
var map = new Map({
basemap: "", // 底图置空
layers: [basemaplayer], // 添加自定义的layer为底图
});
// 创建一个mapView并绑定页面元素
var view = new MapView({
container: "myMapView",
map: map,
zoom: 1, // 缩放比例 值越大图越大
});
// 地图加载完成事件
view.when(function() {
console.log("地图加载完成了!");
resolve();
});
// 定义myMapObject的方法供外部调用
this_.myMapObject.methodForOutSide = function(val){
console.log("methodForOutSide方法被调用了:"+val);
}
this_.myMapObject.map = map;
})
})
},
valueChange(newVal, oldVal, ownerVm, vm) {
console.log("我是视图层,我被逻辑层调用了...");
console.log("我是新数据....");
console.log(newVal);
console.log("我是旧数据....");
console.log(oldVal);
var map = newVal[1];
},
},
mounted() {
// 页面初始化完成后
var this_ = this;
this.createMapView().then(function(){
console.log("加载地图的promise执行结束了....")
// 打印地图对象
console.log(this_.myMapObject.map);
// 调用createMapView()内部的方法
this_.myMapObject.methodForOutSide();
// renderJs主动调用逻辑层的方法
this_.$ownerInstance.callMethod('methodForRenderJs',{val1:"参数1",val2:"参数2"});
});
},
}
</script>
<style>
/deep/.esri-widget--button {
display: none;
}
/deep/.esri-attribution__powered-by {
display: none;
}
/deep/.esri-view .esri-view-surface--inset-outline:focus::after {
outline: none;
}
</style>
posted on 2022-03-21 17:48 northwest 阅读(3092) 评论(0) 编辑 收藏 举报