function initRelationHandlers (type, handler, target, ctx) {
|
if (!handler) {
|
return
|
}
|
const name = `_$${type}Handlers`;
|
(ctx[name] || (ctx[name] = [])).push(function () {
|
handler.call(ctx, target)
|
})
|
}
|
|
function initLinkedHandlers (relation, target, ctx) {
|
const type = 'linked'
|
const name = relation.name
|
const relationNodes = ctx._$relationNodes || (ctx._$relationNodes = Object.create(null));
|
(relationNodes[name] || (relationNodes[name] = [])).push(target)
|
initRelationHandlers(type, relation[type], target, ctx)
|
}
|
|
function initUnlinkedHandlers (relation, target, ctx) {
|
const type = 'unlinked'
|
initRelationHandlers(type, relation[type], target, ctx)
|
}
|
|
function findParentRelation (parentVm, target, type) {
|
const relations = parentVm &&
|
parentVm.$options.mpOptions &&
|
parentVm.$options.mpOptions.relations
|
|
if (!relations) {
|
return []
|
}
|
const name = Object.keys(relations).find(name => {
|
const relation = relations[name]
|
return relation.target === target && relation.type === type
|
})
|
if (!name) {
|
return []
|
}
|
return [relations[name], parentVm]
|
}
|
|
function initParentRelation (vm, childRelation, match) {
|
const [parentRelation, parentVm] = match(vm, vm.$options.mpOptions.path)
|
if (!parentRelation) {
|
return
|
}
|
|
initLinkedHandlers(parentRelation, vm, parentVm)
|
initLinkedHandlers(childRelation, parentVm, vm)
|
|
initUnlinkedHandlers(parentRelation, vm, parentVm)
|
initUnlinkedHandlers(childRelation, parentVm, vm)
|
}
|
|
function initRelation (relation, vm) {
|
const type = relation.type
|
if (type === 'parent') {
|
initParentRelation(vm, relation, function matchParent (vm, target) {
|
return findParentRelation(vm.$parent, target, 'child')
|
})
|
} else if (type === 'ancestor') {
|
initParentRelation(vm, relation, function matchAncestor (vm, target) {
|
let $parent = vm.$parent
|
while ($parent) {
|
const ret = findParentRelation($parent, target, 'descendant')
|
if (ret.length) {
|
return ret
|
}
|
$parent = $parent.$parent
|
}
|
return []
|
})
|
}
|
}
|
|
export function initRelations (vm) {
|
const {
|
relations
|
} = vm.$options.mpOptions || {}
|
if (!relations) {
|
return
|
}
|
Object.keys(relations).forEach(name => {
|
initRelation(relations[name], vm)
|
})
|
}
|
|
export function handleRelations (vm, type) {
|
// TODO 需要移除 relationNodes
|
const handlers = vm[`_$${type}Handlers`]
|
if (!handlers) {
|
return
|
}
|
handlers.forEach(handler => handler())
|
}
|