标注列表 最后更新时间: 2021年01月22日
MarkerList,即点标注(Marker)+ 列表(List),是一类非常典型的地图应用,通常包括如下的需求片段:
- 存在一组包含经纬度信息的数据,比如连锁店面的信息,地点的搜索结果等等,每一条数据可称为“数据项”。
- 要在地图上用Marker标识出各个数据项的位置;Marker上支持打开一个信息窗体(infoWindow)来展示数据项的相关信息。
- 要构建一个列表(如上方示例的右侧部分),每个列表节点(ListElement)展示数据项的相关信息,比如名称,地址,介绍等等
- 要支持互动,比如选中,点击Marker,点击列表节点,鼠标Hover列表节点等等;还要支持联动,比如点击列表节点时,要把关联的Marker移动到地图中心等等。
借助MarkerList,开发者可以摆脱一些较复杂的逻辑(比如数据、Marker、列表、事件的管理), 将精力集中到如下层面:
- UI展示:给定一条数据,要构造什么样的Marker,什么样的列表节点,什么样的信息窗体
- 事件处理:给定一个事件,比如makerClick,各个关联的对象(数据项,Marker,列表节点)怎么响应这个事件
名词释义
如何使用
1、引入UI组件库
2、MarkerList依赖jQuery或者Zepto,请参见这里确定是否需要进行DomLibrary设置。
3、加载MarkerList(模块名:ui/misc/MarkerList
),示例
//加载MarkerList,loadUI的路径参数为模块名中 'ui/' 之后的部分
AMapUI.loadUI(['misc/MarkerList'], function(MarkerList) {
//启动页面
initPage(MarkerList);
});
function initPage(MarkerList) {
//创建一个实例
var markerList = new MarkerList({
map: map, //关联的map对象
listContainer: 'my-list', //列表的dom容器的节点或者id, 用于放置getListElement返回的内容
getDataId: function(dataItem, index) {
//返回数据项的Id
return dataItem.id;
},
getPosition: function(dataItem) {
//返回数据项的经纬度,AMap.LngLat实例或者经纬度数组
return dataItem.position;
},
getMarker: function(dataItem, context, recycledMarker) {
var content = '标注: ' + (context.index + 1) + '',
label = {
offset: new AMap.Pixel(16, 18),
content: content
};
if (recycledMarker) {
//存在可回收利用的marker,直接setLabel返回
recycledMarker.setLabel(label);
return recycledMarker;
}
//返回一个新的Marker
return new AMap.Marker({
label: label
});
},
getInfoWindow: function(dataItem, context, recycledInfoWindow) {
var tpl = '<p><%- dataItem.id %>:<%- dataItem.desc %><p>';
//MarkerList.utils.template支持underscore语法的模板
var content = MarkerList.utils.template(tpl, {
dataItem: dataItem,
dataIndex: context.index
});
if (recycledInfoWindow) {
//存在可回收利用的infoWindow, 直接setContent返回
recycledInfoWindow.setContent(content);
return recycledInfoWindow;
}
//返回一个新的InfoWindow
return new AMap.InfoWindow({
offset: new AMap.Pixel(0, -23),
content: content
});
},
getListElement: function(dataItem, context, recycledListElement) {
var tpl = '<p><%- dataItem.id %>:<%- dataItem.desc %><p>';
var content = MarkerList.utils.template(tpl, {
dataItem: dataItem,
dataIndex: context.index
});
if (recycledListElement) {
//存在可回收利用的listElement, 直接更新内容返回
recycledListElement.innerHTML = content;
return recycledListElement;
}
//返回一段html,MarkerList将利用此html构建一个新的dom节点
return '<li>' + content + '</li>';
}
});
//监听选中改变
markerList.on('selectedChanged', function(event, info) {});
//监听Marker和ListElement上的点击,详见markerEvents,listElementEvents
markerList.on('markerClick listElementClick', function(event, record) {});
//构建数据源,数据项本身没有格式要求,但需要支持getDataId和getPosition
var data = [{
id: 'A',
position: [116.020764, 39.904989],
desc: '数据_1'
}, {
id: 'B',
position: [116.405285, 39.904989],
desc: '数据_2'
}, {
id: 'C',
position: [116.789806, 39.904989],
desc: '数据_3'
}];
//绘制数据源,Let's go!
markerList.render(data);
//清除数据
//markerList.render([]);
}
接口文档
构造参数
参数名称 | 类型 | 说明 |
---|---|---|
| 地图对象实例,用于显示相关的Marker | |
|
| 列表容器的dom节点或者Id |
|
| 返回数据项中的经纬度信息
比如:
|
|
| 返回数据项Id,Id具备唯一性;实在没有的话,可以用数据项索引(dataIndex)代替。
比如:
|
|
| 根据数据项,返回一个Marker或者其子类(比如SimpleMarker)的实例(不需要设置map和position)
推荐的做法是:
|
|
| 根据数据项,返回一个InfoWindow或者其子类(比如SimpleInfoWindow)的实例( 不需要设置map和position )
推荐的做法是:
|
|
| 根据数据项,返回一个Dom节点,或者该节点的html(outerHTML)构造
推荐的做法是: recycledListElement 参数为空时创建新的节点或者构建html(可以借助
|
|
| 列表节点上需要被监听的全部事件名称(列表的Dom节点触发的事件),默认的取值是: 如何监听: 监听的事件名称为
监听多个事件时用空格分开,比如取值包括
|
|
| Marker上需要被监听的全部事件(由Marker触发的事件)名称 ,默认的取值是:
如何监听: 监听的事件名称为
监听多个事件时用空格分开,比如取值包括
|
|
| InfoWindow上需要被监听的事件列表(InfoWindow的Dom容器触发的事件),默认的取值是: 如何监听: 监听的事件名称为
监听多个事件时用空格分开,比如取值包括
|
|
| 是否在绘制后自动调整地图视野以适合全部Marker,默认 |
|
| 选中状态时,列表节点和Marker的Dom容器上附带的class,多个class name可以用空格分开,默认取值: |
|
| 默认触发相关记录被“选中”(单选)的事件名称(MarkerList自身触发的事件),默认的取值是:
如果需要调整选中的触发行为,可以将此值置空,并借助事件监听和 |
|
| 可选值,定义选中后需要执行的默认行为, 包括:
如果要修改这些行为,请将该值置null,并监听 |
方法
方法名称 | 返回值 | 说明 |
---|---|---|
| 传入数据源data,绘制图面;图面绘制后,可以通过 | |
|
| 返回数据源数组(注意,这个数组不是上述render中传入的data,而是一个浅层的拷贝,即每个元素的引用没变,但数组本身是个新数组) |
|
| 返回所有记录,每条记录中包括数据项,数据项Id,数据项索引及其关联的Marker、ListElement。通常要等到 |
|
| 返回有数据对应的所有的列表节点 |
|
| 返回有数据对应的所有的Marker |
|
| 返回 InfoWindow ;因为 InfoWindow 每次只能显示一个,所以与Marker不同,所有的数据项共用唯一的一个InfoWindow |
|
| 遍历所有记录,返回其中 record.id == id 的记录。 |
|
| 遍历所有记录,返回其中 record.index == index 的记录 |
|
| 遍历所有记录,返回其中 record.data == dateItem 的记录 |
|
| 遍历所有记录,返回其中 record.marker == marker 的记录 |
|
| 遍历所有记录,返回其中 record.listElement == listElement 的记录 |
|
| 返回InfoWindow关联的数据项Id |
|
| 返回列表节点关联的数据项Id |
|
| 返回Marker管理的数据项Id |
|
| 返回当前选中的数据项Id |
|
| 返回当前处于选中状态的记录 |
|
| 判断传入的数据项Id是否是当前选中的Id |
| 清除选中 | |
|
| 遍历所有记录,选中其中 record.id == id 的记录。 |
|
| 遍历所有记录,选中其中 record.index == index 的记录 |
|
| 遍历所有记录,选中其中 record.data == dataItem 的记录 |
|
| 遍历所有记录,选中其中 记录总数-1-record.index == reverseIndex (即倒叙索引)的记录 |
|
| 选中传入的记录。
|
| 根据record的相关信息(包括位置,内容等)展开InfoWindow | |
| 关闭InfoWindow | |
| 清空数据以及关联的UI对象,包括Marker和列表节点 | |
| 清空回收站,回收站包括未被使用的Marker和列表节点。 某些场景下可能需要,比如绘制的第一份数据长度是100,后面的数据长度都是20,那么回收站中将存在规模在80左右的多余资源,此时可以考虑在 | |
| 触发 eventName 事件 对应的监听方法为:
监听方法的
| |
| 触发 eventName 事件,并利用 对应的监听方法为:
监听方法的
| |
| 监听 eventName 事件,多个事件用空格分隔 | |
| 注销 eventName 事件,多个事件用空格分隔 |
静态属性
属性名称 | 说明 |
---|---|
MarkerList . | utils下包含一些辅助工具,包括: 1、 underscore的模板方法,用法示例:
underscore模板语法包括以下三种:
2、 即DomLibrary (jQuery/Zepto),用法示例:
|
事件
事件名称 | 参数 | 说明 |
---|---|---|
|
| 数据绘制完成后触发 |
|
| 选中改变时触发
某些场景下可能需要区别对待不同来源的选中行为,比如点击Marker选中时闪动关联的列表节点,点击列表节点选中时闪动关联的Marker,此时可以依靠 |
|
| 与构造参数中的
则会触发:
|
|
| 与构造参数中的
则会触发:
|
|
| 与构造参数中的 则会触发:
|
|
| 记录中的 |
|
| 记录中的 |
|
| 记录中的 |
|
| 记录中的 |
|
| 记录中的 |
|
| 记录中的 |
|
| 记录中的 |
|
| 记录中的 |
|
| 记录中的 |
|
| 记录中的 |
|
| 记录中的 |
|
| 记录中的 |
附带其他覆盖物
开发者如果需要附带绘制多边形,圆,线段等其他类型的覆盖物,可以通过监听 markerAddToMap
和markerRemoveFromMap
事件,在Marker添加到地图上时创建相关的覆盖物,并在移除时一并移除。如果开发者不希望看到Marker,可以在Marker的构造参数中增加 visible:false