Knotenoperationen
In diesem Abschnitt geht es darum, Knotenoperationen zu beobachten und abzufangen; außerdem werden Möglichkeiten vorgestellt, Knoten programmatisch zu bearbeiten.
Knotenoperationen abonnieren
Operationen der Nutzerinnen und Nutzer auf der Mindmap können wir abonnieren, indem wir auf Operationsereignisse lauschen. Das ist so einfach wie das Lauschen auf DOM-Ereignisse:
mind.bus.addListener('operation', (operation) => {
console.log(operation)
// { name: 'addChild', target: NodeObj }
// { name: 'insertSibling', target: NodeObj, position: 'before' | 'after' }
// { name: 'copyNodes', target: NodeObj[] }
// { name: 'moveNodesIn', target: NodeObj[], destination: NodeObj }
})
mind.bus.addListener('selectNodes', (nodes) => {
console.log(nodes)
})
// Folding is reported through the `operation` event:
mind.bus.addListener('operation', (op) => {
if (op.name === 'expandNode' || op.name === 'collapseNode') {
console.log('node: ', op.target)
console.log('silent: ', op.silent)
}
})
Das am häufigsten verwendete Ereignis ist operation, das alle Knotenoperationen umfasst.
operation ist eine diskriminierte Union über name:
targetist der betroffene Knoten – ein einzelnesNodeObjoder einNodeObj[]bei Stapeloperationen (copyNodes,removeNodes,moveNodes*).destinationist das Verschiebungsziel, undpositionist'before' | 'after'fürinsertSibling.- Ein- und Ausklappen erscheinen auf
operationalsexpandNode/collapseNode.op.silentisttruebei internen stillen Ausklappvorgängen und{ silent: true }-Aufrufen, die niemals Historieneinträge erzeugen. - Knotenmethoden erwarten Arrays:
copyNodes([node], to)sowiemoveNodesIn/moveNodesBefore/moveNodesAfter(nodes, to).
Die vollständige Liste findest du im v6-API-Leitfaden.
Guards für Knotenoperationen
Wie der Name schon sagt, können Guards für Knotenoperationen das Verhalten einer bestimmten Knotenoperation abfangen.
Setze in der Konfiguration das Objekt before: Die Eigenschaftsnamen entsprechen den Knotenoperationen, die Werte sind Funktionen, die einen Boolean zurückgeben (oder einen in ein Promise verpackten Boolean).
let mind = new MindElixir({
// ...
before: {
insertSibling(type, el, node) {
console.log(type, el, node)
if (this.currentNode?.nodeObj.parent?.root) {
return false
}
return true
},
async addChild(el, node) {
await sleep()
if (this.currentNode?.nodeObj.parent?.root) {
return false
}
return true
},
},
})
Mit async in Operations-Guards lassen sich auch Fälle abfangen, in denen asynchrone Informationen nötig sind, um über den Fortgang zu entscheiden.
Programmatische Knotenoperationen
Mind Elixir Core stellt eine API zur direkten Bearbeitung von Knoten bereit:
{
insertSibling: (
this: MindElixir,
type: 'before' | 'after',
el?: Topic,
node?: NodeObj
) => Promise<void>
insertParent: (this: MindElixir, el?: Topic, node?: NodeObj) => Promise<void>
addChild: (this: MindElixir, el?: Topic, node?: NodeObj) => Promise<void>
copyNodes: (this: MindElixir, tpcs: Topic[], to: Topic) => Promise<void>
moveUpNode: (this: MindElixir, el?: Topic) => Promise<void>
moveDownNode: (this: MindElixir, el?: Topic) => Promise<void>
removeNodes: (this: MindElixir, tpcs: Topic[]) => Promise<void>
moveNodesIn: (this: MindElixir, from: Topic[], to: Topic) => Promise<void>
moveNodesBefore: (this: MindElixir, from: Topic[], to: Topic) => Promise<void>
moveNodesAfter: (this: MindElixir, from: Topic[], to: Topic) => Promise<void>
beginEdit: (this: MindElixir, el?: Topic) => Promise<void>
setNodeTopic: (this: MindElixir, el: Topic, topic: string) => Promise<void>
}
Wenn wir beispielsweise mit insertSibling einen Geschwisterknoten zum Knoten mit der ID d6e5f69edb6336c3 hinzufügen möchten, gehen wir so vor:
mind.insertSibling(MindElixir.E('d6e5f69edb6336c3'))
MindElixir.E liefert das DOM-Objekt eines Knotens anhand seiner ID. Viele APIs von Mind Elixir Core verwenden Topic als Typ für DOM-Objekte; mit der Funktion E erhältst du sie.