import Event from '../event' import Const from './Const' import distDataParser from './distDataParser' import AreaNode from './AreaNode' export default class DistrictExplorer extends Event { _opts: any _areaNodesForLocating: any _areaNodeCache: any constructor(opts) { super() this._opts = Object.assign( { distDataLoc: '//webapi.amap.com/ui/1.1/ui/geo/DistrictExplorer/assets/d_v2' }, opts ) this._areaNodesForLocating = null this._areaNodeCache = {} this._opts.preload && this.loadMultiAreaNodes(this._opts.preload) } setAreaNodesForLocating(areaNodes) { areaNodes ? Array.isArray(areaNodes) || (areaNodes = [areaNodes]) : (areaNodes = []) this._areaNodesForLocating = areaNodes || [] } _loadJson(src, callback) { const self = this return fetch(src, { headers: { Accept: 'application/json' } }) .then((res) => res.json()) .then((json) => { callback && callback.call(self, null, json) }) .catch((error) => { if (!callback) throw error callback(error) }) } _getAreaNodeDataFileName(adcode) { return `an_${adcode}.json` } _getAreaNodeDataSrc(adcode) { return `${this._opts.distDataLoc}/${this._getAreaNodeDataFileName(adcode)}` } loadAreaTree(callback) { this._loadJson(`${this._opts.distDataLoc}/area_tree.json`, callback) } loadCountryNode(callback) { this.loadAreaNode(Const.ADCODES.COUNTRY, callback) } loadMultiAreaNodes(adcodes, callback?: any) { let results: any[] = [], done = !1, left function buildCallback(i) { return function (error, areaNode) { if (!done) { left-- if (error) { callback && callback(error) done = !0 } else { results[i] = areaNode 0 === left && callback && callback(null, results) } } } } if (adcodes && adcodes.length) { const len = adcodes.length, left = len for (let i = 0; i < len; i++) this.loadAreaNode(adcodes[i], callback ? buildCallback(i) : null) } else callback && callback(null, []) } loadAreaNode(adcode, callback, thisArg?: any, canSync?: any) { thisArg = thisArg || this if (this._areaNodeCache[adcode]) { if (callback) { const areaNode = this._areaNodeCache[adcode] canSync ? callback.call(thisArg, null, areaNode, !0) : setTimeout(function () { callback.call(thisArg, null, areaNode) }, 0) } } else this._loadJson(this._getAreaNodeDataSrc(adcode), (err, data) => { if (err) callback && callback.call(thisArg, err) else { this._buildAreaNode(adcode, data) callback && callback.call(thisArg, null, this._areaNodeCache[adcode]) } }) } getLocalAreaNode(adcode) { return this._areaNodeCache[adcode] || null } _buildAreaNode(adcode, distData) { if (!this._areaNodeCache[adcode]) { if (!distData) throw new Error(`Empty distData: ${adcode}`) const areaNode = new AreaNode(adcode, distDataParser.buildData(distData), this._opts) this._areaNodeCache[adcode] = areaNode this._areaNodesForLocating || (this._areaNodesForLocating = [areaNode]) } } clearAreaNodeCacheByAdcode(adcode) { const nodeCache = this._areaNodeCache delete nodeCache[adcode] return !0 } destroy() { this._areaNodesForLocating = null this._areaNodeCache = null this._opts = null } }