扩展教程:http://leafletjs.com/examples/extending/extending-1-classes.html
翻译
该教程介绍扩展Leaflet最常用的方式。
注意:本文假定你熟练掌握了一下知识:
- JavaScript
- DOM处理
- 面向对象的程序设计(理解概念,如类,实例,继承,方法和属性)
Leaflet 1.0.0 简化的UML 类图。Leaflet拥有60多个JavaScript类,因此UML图有点大,使用L.ImageOverlay来制作可缩放的图片。
可缩放图片地址:http://leafletjs.com/examples/extending/class-diagram.html
从技术的角度来看,传单可以以不同的方式扩展:
- 最常见的:创建一个新的子类
L.Layer
,L.Handler,
L.Control
,L.Class.extend()
- 层移动时,地图是移动/缩放
- 处理程序是不可见的,解释浏览器事件
- 控制固定界面元素
- 包括更多的功能,在现有的类
L.Class.include()
- 添加新的方法和选择
- 改变一些方法
- 使用
addInitHook
运行额外的构造函数代码。
- 一个已经存在的类(类怎样更换零部件更换方法与作品)
L.Class.include()
。
L.Class
L.Class.extend()
为类、方法和属性命名时注意遵循以下命名习惯:
- 函数、方法、属性和工厂方法名称应该使用小驼峰风格
- 类名称应该使用大驼峰风格
- 私有属性和方法以下划线(_)开始。这种写法并不是真正将属性和方法私有化,只是提醒开发者不要直接使用它们
L.Class.include()
如果某个类已经定义了,可以使用.include()重新定义已有的属性、方法或者添加新的属性或者方法。
MyDemoClass.include({ // Adding a new property to the class _myPrivateProperty: 78, // Redefining a method myDemoMethod: function() { return this._myPrivateProperty; } }); var mySecondDemoInstance = new MyDemoClass(); // This will output "78" console.log( mySecondDemoInstance.myDemoMethod() ); // However, properties and methods from before still exist // This will output "42" console.log( mySecondDemoInstance.myDemoProperty );
L.Class.initialize()
在OOP中,类会拥有一个构造器方法。在Leaflet中的L.Class中,构造器方法被命名为initialize。
如果你的类拥有一些特定的选项(options),可以在构造器中使用L.setOptions()方法来初始化选项(options)。这个函数可以将提供的选项和类中的默认选项合并。
var MyBoxClass = L.Class.extend({ options: { width: 1, height: 1 }, initialize: function(name, options) { this.name = name; L.setOptions(this, options); } }); var instance = new MyBoxClass('Red', {width: 10}); console.log(instance.name); // Outputs "Red" console.log(instance.options.width); // Outputs "10" console.log(instance.options.height); // Outputs "1", the default
Leaflet使用特殊的方式处理选项属性(options):子类会继承父类中的选项属性(options)。
var MyCubeClass = MyBoxClass.extend({ options: { depth: 1 } }); var instance = new MyCubeClass('Blue'); console.log(instance.options.width); console.log(instance.options.height); console.log(instance.options.depth);
子类执行父类构造器和自身的构造器也很常见的行为。在Leafleet中可以使用L.Class.addInitHook()实现。这个方法可以在类的initialize()方法刚刚执行之后“挂住”初始化函数,比如:
MyBoxClass.addInitHook(function(){ this._area = this.options.width * this.options.length; });
在initialize()执行(调用setOpstions()的方法)之后会执行该函数。这就意味着this.options在hook执行之前已经存在并赋值了。
addInitHook有一种可选的语法,可以使用方法名称和方法中的参数作为addInitHook的参数。
var MyCubeClass = MyBoxClass.extend({ options: { depth: 1 } }); var instance = new MyCubeClass('Blue'); console.log(instance.options.width); console.log(instance.options.height); console.log(instance.options.depth);
父类的方法
通过访问父类的原型可以调用父类中的方法,使用Function.call(...)可以实现。比如,可以在L.FeatureGroup的代码中看到:
调用父类的构造器可以使用相同的方式,使用如下的方式替代:ParrentClass.prototype.initialize.call(this,...)。
工厂方法
大多数的Leaflet类拥有对应的工厂方法。工厂方法拥有和对应类相同的名字,只不过类使用大驼峰风格而工厂方法使用小驼峰风格。
function myBoxClass(name, options) { return new MyBoxClass(name, options); }
命名风格
为Leaflet类插件命名时请遵循一下命名习惯:
- 永远不要在你的插件中暴露全局变量
- 如果你拥有一个新类,将它直接放在L命名空间中(L.MyPlugin)
- 如果你继承一个已有的类,将它作为已有类的子属性
原文地址:http://blog.csdn.net/naipeng/article/details/53666394