Openlayers 源码分析-BaseObject

要分析框架的源码,首先需要从基类开发,在OpenlayersBaseObject可以说是很多类的基类,比如MapViewLayerOverlay等这些类,都 是继承于BaseObject,就先从BaseObject这个类来开始看。BaseObject并不是最顶端的基础,也是继承于其它的类,继承关系如下所示:

Disposable》Target》Observable》BaseObject

下面就这几个类来进行分析。

1.Disposable

Disposable可以说是所有相关类的老祖宗,该类的代码很简洁,提供的方法也就两个。分别是dispose()disposeInternal()。该类的主要作用是清除对象和事件等信息,一般在子类通过重写disposeInternal()方法处理清空的逻辑,调用dispose()来执行清除的操作。

2.Target

Target是一个目标对象,主要用于管理相关的事件,添加事件,移除事件、派发事件等操作都是使用该类来处理。

2.1构造函数

Target 的构造函数主要是用于实例化pendingRemovals_dispatching_dispatching_等属性,定义属性的时候在属性名后面加了下划线表示为私有变量。

constructor(opt_target) {

    super();

    /**
     * @private
     * @type {*}
     * 参数信息
     */
    this.eventTarget_ = opt_target;

    /**
     * @private
     * @type {!Object}
     * 待删除的事件
     */
    this.pendingRemovals_ = {};

    /**
     * @private
     * @type {!Object}
     * 派发中的事件
     */
    this.dispatching_ = {};

    /**
     * @private
     * @type {!Object>}
     * 所有事件
     */
    this.listeners_ = {};

  }

2.2添加事件

添加事件的逻辑为先根据typelisteners_中获取,如果没被添加过,就先初始化数组,然后再进行添加。

addEventListener(type, listener) {
    if (!type || !listener) {//type和listener不能为空
      return;
    }
    let listeners = this.listeners_[type];
    if (!listeners) {//为空时初始化数组
      listeners = [];
      this.listeners_[type] = listeners;
    }
    if (listeners.indexOf(listener) === -1) {
      listeners.push(listener);
    }
  }

2.3事件派发

使用dispatchEvent可以对事件进行派发,派发完成后,执行removeEventListener进行删除。

删除事件

该方法主要是通过typelistenerlisteners_中对应的事件删除。

removeEventListener(type, listener) {
    const listeners = this.listeners_[type];
    if (listeners) {
      const index = listeners.indexOf(listener);
      if (index !== -1) {
        if (type in this.pendingRemovals_) {
          // make listener a no-op, and remove later in #dispatchEvent()
          listeners[index] = VOID;
          ++this.pendingRemovals_[type];
        } else {
          listeners.splice(index, 1);
          if (listeners.length === 0) {
            delete this.listeners_[type];
          }
        }
      }
    }
  }
dispatchEvent(event) {
    //判断event类型
    const evt = typeof event === 'string' ? new Event(event) : event;
    const type = evt.type;
    if (!evt.target) {//找到事件的上档对象
      evt.target = this.eventTarget_ || this;
    }
    const listeners = this.listeners_[type];
    let propagate;
    if (listeners) {
      if (!(type in this.dispatching_)) {//判断有没有正在派发的
        this.dispatching_[type] = 0;
        this.pendingRemovals_[type] = 0;
      }
      ++this.dispatching_[type];//开始派发事件
      for (let i = 0, ii = listeners.length; i < ii; ++i) {
        if (listeners[i].call(this, evt) === false || evt.propagationStopped) {
          propagate = false;
          break;
        }
      }
      --this.dispatching_[type];//事件派发结束
      if (this.dispatching_[type] === 0) {
        let pendingRemovals = this.pendingRemovals_[type];
        delete this.pendingRemovals_[type];
        while (pendingRemovals--) {//移除事件
          this.removeEventListener(type, VOID);
        }
        delete this.dispatching_[type];
      }
      return propagate;
    }
  }

3.Observable

Observable是一个观察者对象,这里主要运行了设计模式中的观察者模式,用于订阅和发布事件,该类主要包括ononceun等方法。

3.1on

用于添加事件,主要是使用listen方法来调用Target类的addEventListener来添加。

on(type, listener) {
    if (Array.isArray(type)) {//数组,多个事件使用的是同一个函数回调
      const len = type.length;
      const keys = new Array(len);
      for (let i = 0; i < len; ++i) {//遍历数组进行添加
        keys[i] = listen(this, type[i], listener);
      }
      return keys;
    } else {
      return listen(this, /** @type {string} */ (type), listener);
    }
  }

3.2once

同样的事件类型不能重复添加。

 once(type, listener) {
    if (Array.isArray(type)) {
      const len = type.length;
      const keys = new Array(len);
      for (let i = 0; i < len; ++i) {
        keys[i] = listenOnce(this, type[i], listener);
      }
      return keys;
    } else {
      return listenOnce(this, /** @type {string} */ (type), listener);
    }
  }

3.3 un

用于删除事件,主要调用Target类的removeEventListener来移除事件。

un(type, listener) {
    if (Array.isArray(type)) {
      for (let i = 0, ii = type.length; i < ii; ++i) {
        this.removeEventListener(type[i], listener);
      }
    } else {
      this.removeEventListener(type, listener);
    }
  }

4.BaseObject

BaseObject主要用于往对象中动态添加属性和属性值,在初使化的时候,可以通过构造函数来传递默认添加的对象,然后调用setPropertiesvalues_赋值,如下所示:

 constructor(opt_values) {
    super();
    getUid(this);
    this.values_ = {};

    if (opt_values !== undefined) {//设置属性
      this.setProperties(opt_values);
    }
  }

setProperties(values, opt_silent) {
    for (const key in values) {
      this.set(key, values[key], opt_silent);
    }
  }

在调用set方法的时候,其中一个流程用到了notify方法,使用该方法可以通知属性的变化,如下所示:

set(key, value, opt_silent) {
    if (opt_silent) {
      this.values_[key] = value;
    } else {
      const oldValue = this.values_[key];
      this.values_[key] = value;
      if (oldValue !== value) {
        this.notify(key, oldValue);
      }
    }
  }

notify(key, oldValue) {
    let eventType;
    eventType = getChangeEventType(key);
    //派发‘change:属性名’的事件
    this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
    eventType = ObjectEventType.PROPERTYCHANGE;
    //派发PROPERTYCHANGE事件
    this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
  }

getProperties() {
    return assign({}, this.values_);//复制一个新的对象返回
  }

BaseObject先分析到此了,代码一路看下来,不得不说这个框架的代码写的很好,很简洁,很有参考价值,设计模式也用的很到位,值得慢慢品味。真香!
个人博客

你可能感兴趣的:(Openlayers 源码分析-BaseObject)