Kaynağa Gözat

hack: mark selected item while keeping treeview fast

Martin Kunz 10 ay önce
ebeveyn
işleme
8770db4117

+ 2 - 6
src/components/TheAddressspace.vue

@@ -3,14 +3,10 @@ import { UABaseNode } from '@/ua/UABaseNode';
 import TreeItem from './TreeItem.vue'
 import {useStore} from '@/store'
 import TheContextMenu from './TheContextMenu.vue';
-import { ref } from 'vue';
 const store = useStore()
-
 function selectNode(node: UABaseNode) {
   store.selectedNode=node;
-  selNode.value=node;
 }
-const selNode=ref(UABaseNode.nullBaseNode);
 </script>
 
 <template>
@@ -20,8 +16,8 @@ const selNode=ref(UABaseNode.nullBaseNode);
       <p class="card-text">
       <ul>
         <TheContextMenu>
-          <TreeItem class="item" v-if="store.rootNode != null" :model="store.rootNode"
-            @select-node="(node: UABaseNode) => selectNode(node)" :selected-node="selNode">
+          <TreeItem class="item" v-if="store.rootNode != null" :model="store.rootNode" :selectedNode="store.selectedNode" :markSelected="true"
+            @select-node="(node: UABaseNode) => selectNode(node)" >
           </TreeItem>
         </TheContextMenu>
       </ul>

+ 1 - 2
src/components/TheParent.vue

@@ -22,7 +22,6 @@ function clickNode(clickedNode: UABaseNode) {
 watch(selectedNode, async (newNode, _oldNode) => {
   selectedRefType.value=newNode?.getParentRef()?.referenceType||"";
   selectedParent.value=newNode?.getParent()||UABaseNode.nullBaseNode;
-
 })
 
 function okPressed() {
@@ -55,7 +54,6 @@ function getRefTypes():UABaseNode[] {
         <input readonly type="text" class="form-control" aria-label="Default"
           aria-describedby="inputGroup-sizing-default" :value="selectedParent.displayName">
           <button class="btn btn-light" @click="parentDialogOpen = true">...</button>
-
       </div>
       <div class="input-group mb-3">
         <div class="input-group-prepend">
@@ -73,6 +71,7 @@ function getRefTypes():UABaseNode[] {
     :open="parentDialogOpen" 
     :filter-func="(node: UABaseNode) => filter(node)"
     @cancel="parentDialogOpen = false" 
+    :markSelected="false"
     @select-node="(node) => clickNode(node)">
   </TheTreeDialog>
 </template>

+ 28 - 10
src/components/TreeItem.vue

@@ -1,23 +1,29 @@
 <script setup lang="ts" >
+import { useStore } from '@/store';
 import { UABaseNode } from '@/ua/UABaseNode';
-import { ref, computed } from 'vue'
+import { storeToRefs } from 'pinia';
+import { ref, computed, watch } from 'vue'
+
+
+const store = useStore()
+const { selectedNode } = storeToRefs(store)
+
 
 const props = defineProps<{
   model: UABaseNode,
   filterFunc?: Function,
-  selectedNode: UABaseNode
+  markSelected: Boolean
 }>();
 
+const emit = defineEmits(['selectNode']);
+
 const isOpen = ref(false)
+const selected = ref(false)
 const isFolder = computed(() => {
   const children=props.model?.getChildren();
   return children && children.length;
 })
 
-const isSelected = computed(() => {
-  return (props.selectedNode?.nodeId.toString()===props.model?.nodeId.toString())
-})
-
 const isFiltered = computed(() => {
   if(!props.filterFunc)
     return false;
@@ -31,14 +37,26 @@ const children = computed(() => {
 function toggle() {
   isOpen.value = !isOpen.value
 }
+function selectNode(node:UABaseNode) {
+  emit('selectNode', node);
+  //this hack avoids updating props and re-evaluating the whole tree on select
+  //Needs ref to store unfortunately
+  if(props.markSelected) {
+    selected.value=true;
+    const unwatch = watch(selectedNode, () => {
+      selected.value=false;
+      unwatch();
+    });
+  }
+}
 </script>
 
 <template>
   <li>
     <div v-if="model"  :class="{ bold: isFolder }">
       <span v-if="isFolder" @click="toggle">[{{ isOpen ? '-' : '+' }}]</span>
-      <span @click.stop="$emit('selectNode', model)"  class="itemtext" :class="[(isFiltered?'disabled':''), 
-         isSelected?'selected':'' ]">
+      <span @click.stop="selectNode(model)"  class="itemtext" :class="[(isFiltered?'disabled':''), 
+         selected?'selected':'' ]">
         {{ model.displayName }}
       </span>
     </div>
@@ -47,10 +65,10 @@ function toggle() {
           class="item"
           :filter-func = "$props.filterFunc"
           @select-node="(node: UABaseNode) => $emit('selectNode', node)"
+          :markSelected="markSelected"
           v-for="child in children"
           v-bind:key="child.nodeId.toString()"
-          :model="child"
-          :selectedNode="$props.selectedNode">
+          :model="child">
         </TreeItem>
     </ul>
   </li>