Files
vue-google-maps-community-fork/src/utils/bindProps.js
2021-02-13 16:09:48 +01:00

75 lines
2.4 KiB
JavaScript

import WatchPrimitiveProperties from '../utils/WatchPrimitiveProperties'
function capitalizeFirstLetter (string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}
export function getPropsValues (vueInst, props) {
return Object.keys(props)
.reduce(
(acc, prop) => {
if (vueInst[prop] !== undefined) {
acc[prop] = vueInst[prop]
}
return acc
},
{}
)
}
/**
* Binds the properties defined in props to the google maps instance.
* If the prop is an Object type, and we wish to track the properties
* of the object (e.g. the lat and lng of a LatLng), then we do a deep
* watch. For deep watch, we also prevent the _changed event from being
* $emitted if the data source was external.
*/
export function bindProps (vueInst, googleMapsInst, props, options) {
for (let attribute in props) {
let {twoWay, type, trackProperties, noBind} = props[attribute]
if (noBind) continue
const setMethodName = 'set' + capitalizeFirstLetter(attribute)
const getMethodName = 'get' + capitalizeFirstLetter(attribute)
const eventName = attribute.toLowerCase() + '_changed'
const initialValue = vueInst[attribute]
if (typeof googleMapsInst[setMethodName] === 'undefined') {
throw new Error(`${setMethodName} is not a method of (the Maps object corresponding to) ${vueInst.$options._componentTag}`)
}
// We need to avoid an endless
// propChanged -> event $emitted -> propChanged -> event $emitted loop
// although this may really be the user's responsibility
if (type !== Object || !trackProperties) {
// Track the object deeply
vueInst.$watch(attribute, () => {
const attributeValue = vueInst[attribute]
googleMapsInst[setMethodName](attributeValue)
}, {
immediate: typeof initialValue !== 'undefined',
deep: type === Object
})
} else {
WatchPrimitiveProperties(
vueInst,
trackProperties.map(prop => `${attribute}.${prop}`),
() => {
googleMapsInst[setMethodName](vueInst[attribute])
},
vueInst[attribute] !== undefined
)
}
if (twoWay &&
(vueInst.$gmapOptions.autobindAllEvents ||
vueInst.$attrs[eventName])) {
googleMapsInst.addListener(eventName, (ev) => { // eslint-disable-line no-unused-vars
vueInst.$emit(eventName, googleMapsInst[getMethodName]())
})
}
}
}