写在前面
地图服务中,常常会使用到书签功能,来记录并定位兴趣点或兴趣区域。arcgis api for javascript提供了一个书签小功能,即esri.dijit.Bookmarks。在使用的过程中,发现这个书签功能仅实现了页面缓存兴趣点或兴趣范围的增删改功能,然而,项目中应用时,往往需要连接到数据库,将前台兴趣点或兴趣范围的增删改查功能与后台数据进行交换。在实现这个功能的过程中,也学习了一波dojo中define/declare的使用方法。本文在dojo使用方法部分的介绍,参照学习了官网文档,及《一个de两种意思——谈谈Dojo define 和declare的区别》,感谢作者。
dojo define/declare使用
- define 用于定义一个模块(module),定义之后,这个模块可以被require引用,相当于自定义组件。define的第一个参数引入需要用到的其他模块,使用数组对象。第二个参数描述当前自定义的模块具体功能,并且给第一个参数中引用的模块分别起一个名字,使用函数对象。
- declare 作为 在define 第二个参数function中的return对象,包含三个部分:
- 第一个参数是自定义类名,使用中不定义;
- 第二参数是superclasses超类,是被declare中继承的类,可以为null,可以为一个,也可以为数组对象,当有多个超类的时候,第一个被继承类默认为declare类的base prototype(基础原型类,个人翻译,用于理解),其他的类认为是mixins(混入类), 大概是第一个使用到的超类是最为重要的意思;
- 第三个参数是方法对象,其中有三个比较重要的概念:
- 1、constructor method 构造方法
- 2、inheritance 继承的思想
- 3、this.inherited :使用过程中,通常写法是 this.inherited(arguments); 作用是直接在declare的方法中调用第一个超类中的同名方法,但不能再constructor中使用。
以上是纯属个人理解,可能出现不正确不准确的地方,主要还是要多看dojo官方文档,在之后的学习中,可能需要修正
esri.dijit.Bookmarks的简单改写
-
0、后台准备
- 一张数据表
- 接口:增、删、改、查
-
1、js文件主体
define(["dojo/_base/declare",
"esri/map",
"dojo/dom",
...],
function (declare, Map, dom,..., template) {
return declare([_BaseWidget, _WidgetsInTemplateMixin], {
templateString: template,//使用自定义的内容
startup: function () {
console.log("BookMarkWidget::startup");
this.inherited(arguments);
},
// ... 自定义方法
});
});
复制代码
- 2、书签数据查询方法
getBookmarkInfo: function () {
var bookmarkInfo = null;
xhr(getBookmarkUrl , {
handleAs: "json", // 返回json格式的data
method: "get",
timeout: 3000,
sync: true,
headers: {
'Content-Type': 'application/json'
}
}).then(function(data){
if (data.success === 1) {
bookmarkInfo = data.data;
}
}, function(err){
}, function(evt){
});
return bookmarkInfo;
}
复制代码
- 3、书签删除方法
deleteBookmarkHandler: function (event) {
if (!window.confirm("确定删除吗?")) {
return;
}
var _self = this; //重要步骤
xhr(deleteBookmarkUrl, {
data: dojo.toJson(queryData),
method: "post",
timeout: 3000,
handleAs: "json",
headers: {
'Content-Type': 'application/json'
}
}).then(function(data){
if(data.success === 1) {
// 删除内存中的书签---esri.dijit.Bookmarks自带方法
_self.bookmarks.removeBookmark(name);
// ... 设定一个容器bookmarkData,用于维护数据
}
}, function(err){
}, function(evt){
});
}
复制代码
- 4、书签增加/编辑方法
editBookmarkHandler: function (event) {
var _self = this;
// 编辑书签部分
if (bookmarksLenght == _self.bookmarkData.length) {
// ... 对比获取当前被修改的书签的ID---用于queryData构造
xhr(alterBookmarkUrl, {
data: dojo.toJson(queryData),
handleAs: "json",
method: "post",
timeout: 3000,
headers: {
'Content-Type': 'application/json'
}
}).then(function(data){
if(data.success === 1) {
// 维护bookmarkData数据
}
}, function(err){
}, function(evt){
});
}
// 添加书签部分
else if (bookmarksLenght > _self.bookmarkData.length) {
// 添加同名书签时,阻止书签添加,并删除内存中添加的书签
for (var i = 0; i < _self.bookmarkData.length; i++) {
if (currentName == _self.bookmarkData[i].name ) {
messageAlert(0, "不可添加同名书签!");
var equalNodeId = "dojoUnique" + bookmarksLenght;
domConstruct.destroy(equalNodeId);
return;
}
}
xhr(addBookmarkUrl, {
data: dojo.toJson(queryData),
handleAs: "json",
method: "post",
timeout: 3000,
headers: {
'Content-Type': 'application/json'
}
}).then(function(data){
if(data.success === 1) {
// 隐藏原生删除按钮,添加自定义删除按钮
var image_bookmarkRemove = query(".esriBookmarkRemoveImage")[bookmarksLenght - 1];
var removeButton = domConstruct.toDom("<button class = 'btn_bookmarkRemove' \
title = '移除'\
style = 'width:20px; height:20px;\
background: transparent url(./images/close.gif) no-repeat scroll center center;\
border: 0; float: right;'>\
</button>");
domConstruct.place(removeButton, image_bookmarkRemove, "after");
query(".esriBookmarkRemoveImage").style({display: "none"});
// 监听书签的删除操作
on( query(".btn_bookmarkRemove")[bookmarksLenght - 1], "click", lang.hitch(_self, _self.deleteBookmarkHandler));
// 维护bookmarkData数据
_self.bookmarkData = data.data;
}
}, function(err){
_self.bookmarks.removeBookmark(currentName);
}, function(evt){
});
}
复制代码
- 5、书签实例化:以上的三个方法在书签实例化中使用,或者监听相关操作后进行调用
setbookmark: function (url) {
if (this.bookmarks != "YES") {
return;
}
// 实例化书签
this.bookmarks = new Bookmarks({
map: this.map,
bookmarks: [],
editable: true
},
document.getElementById("bookmarks_div")
);
this.rootUrl = url;
// 获取数据库中所存在的所有bookmarks数据,for循环进行构造bookmarkItem,并addBookmark
this.bookmarkData = this.getBookmarkInfo();
for (var i = 0; i < this.bookmarkData.length; i++) {
var bookmarkItem = {
"extent": {
"spatialReference": {
"wkid": this.bookmarkData[i].wkid
},
"xmin": this.bookmarkData[i].xmin,
"ymin": this.bookmarkData[i].ymin,
"xmax": this.bookmarkData[i].xmax,
"ymax": this.bookmarkData[i].ymax
},
"name": this.bookmarkData[i].name,
"bookmarkItemId": this.bookmarkData[i].id
};
this.bookmarks.addBookmark(bookmarkItem);
// 隐藏原生删除按钮,添加自定义删除按钮
var image_bookmarkRemove = query(".esriBookmarkRemoveImage")[i];
var removeButton = domConstruct.toDom("<button class = 'btn_bookmarkRemove' \
title = '移除'\
style = 'width:20px; height:20px;\
background: transparent url(./images/close.gif) no-repeat scroll center center;\
border: 0; float: right;'>\
</button>");
domConstruct.place(removeButton, image_bookmarkRemove, "after");
query(".esriBookmarkRemoveImage").style({display: "none"});
}
// 监听书签的编辑/删除操作
on(this.bookmarks, "edit", lang.hitch(this, this.editBookmarkHandler));
query(".btn_bookmarkRemove").on("click", lang.hitch(this, this.deleteBookmarkHandler));
}
复制代码
总结
- 1、dojo define/declare的使用还不是很熟练,需要加强学习
- 2、涉及到javascript中this的上下文指代问题,需要深入理解
- 3、dojo自带的数据请求方法:xhr()
- 4、dojo/_base/lang: lang.hitch()的用法
dojo中lang.hitch()的简单用法 - 5、分清dom对象和jquery对象 http://www.jquerycn.cn/a_4561
- 6、dojo.on()用法
- 7、dojo.query()用法