vue-jstree icon indicating copy to clipboard operation
vue-jstree copied to clipboard

@item-toggle is called twice

Open Tzahile opened this issue 5 years ago • 15 comments

I added @item-toggle="ItemToggle" and created the function: ItemToggle( ){ ... }

The function ItemToggle is called twice, why?

Tzahile avatar Aug 08 '18 08:08 Tzahile

I am experiencing this as well..

ventralnet avatar Sep 05 '18 18:09 ventralnet

Probably related. If you are using async data and expand a node the load data call is called twice as well.

ventralnet avatar Sep 05 '18 18:09 ventralnet

experiencing same issue, made an ugly workaround where i would ignore the second toggle with a timeout.

can anyone suggest a fix?

MPalarya avatar Sep 06 '18 08:09 MPalarya

What I am doing is

import _ from 'underscore'

const debouncedItemToggle = _.debounce((model) => {
    // do what you need to do
}, 250);

export default {
     ....
     ....
     onItemToggle(oriNode, model) {
         debouncedItemToggle(model);
     },

     .....
};

ventralnet avatar Sep 06 '18 11:09 ventralnet

I think this is a bug. in tree-item.vue; the handleItemToggle methods changed the status of open and carry out the this.onItemToggle method, but you can see, in watch, on model.opened change, the this.onItemToggle method be carry out again. that is why @item-toggle is called twice

summerstarlee avatar Oct 31 '18 10:10 summerstarlee

The underlying issue here is even worse in my case, because it is causing my (expensive) @async function to be called twice every time a folder is expanded for the first time.

Is there a fix or workaround that would work?

Following is a simple example to reproduce the issue:

<template>
  <v-jstree ref="tree" class="tree" v-bind:data="nodes" v-bind:async="loadChildren" />
</template>

<script>
import VJstree from "vue-jstree"

export default {
  name: "bug",
  data: function() {
    return {
      nodes: []
    }
  },
  methods: {
    loadChildren: function(ctx, cb) {
      var id = ctx.data.id
      var done = function() {
        console.log("Children loaded")
        return cb( [{text: "Rabbit Hole", isLeaf: false}] )
      }
      console.log("Simulating long time loading children for node " + id + "...")
      setTimeout(done, 2000)
    }
  },
  components: {
    VJstree
  }
}
</script>

<style>
.tree {
  width: 400px;
  height: 400px;
  border: 1px solid #999;
  float: left;
  overflow: scroll;
}
</style>

which produces the following console output...

bug.vue:22 Simulating long time loading children for node undefined...
bug.vue:19 Children loaded
bug.vue:22 Simulating long time loading children for node 2...
bug.vue:22 Simulating long time loading children for node 2...
bug.vue:19 Children loaded
bug.vue:19 Children loaded
bug.vue:22 Simulating long time loading children for node 6...
bug.vue:22 Simulating long time loading children for node 6...
bug.vue:19 Children loaded
bug.vue:19 Children loaded
bug.vue:22 Simulating long time loading children for node 10...
bug.vue:22 Simulating long time loading children for node 10...
bug.vue:19 Children loaded
bug.vue:19 Children loaded

sburr avatar Jan 04 '19 18:01 sburr

@sburr see what I posted above as a workaround. You will have to debounce the call to load your children so it only happens once. Dirty, but effective.

ventralnet avatar Jan 04 '19 18:01 ventralnet

Thank you. I did read that but had missed a nuance in the way that underscore's debounce method works in an effort to avoid yet another dependency.

sburr avatar Jan 04 '19 19:01 sburr

This repo may interest you if you don't want to import more libs

https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore

On Fri, Jan 4, 2019, 2:44 PM Steven Burr <[email protected] wrote:

Thank you. I did read that but had missed a nuance in the way that underscore's debounce method works in an effort to avoid yet another dependency.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/zdy1988/vue-jstree/issues/67#issuecomment-451548454, or mute the thread https://github.com/notifications/unsubscribe-auth/AAp45bEdCQkR8PpHCAgoKDoXJeuVjMQnks5u_680gaJpZM4VzeKO .

ventralnet avatar Jan 05 '19 02:01 ventralnet

If you are using async data and expand a node the load data call is called twice as well.

I'm experiences this also. Annoying issue..

jupe avatar Mar 17 '20 20:03 jupe

What I am doing is

import _ from 'underscore'

     .....
};

Some more details for a quick workaround in tree.vue using TypeScript library ts-debounce:

import { debounce } from 'ts-debounce';
....
const debouncedItemToggle = debounce((proxyForThis, oriNode, oriItem, e) => {
  if (oriNode.model.opened) {
    proxyForThis.handleAsyncLoad(oriNode.model[proxyForThis.childrenFieldName],
      oriNode,
      oriItem,
    );
  }
  proxyForThis.$emit('item-toggle', oriNode, oriItem, e);
}, 250);

export default {
     ....
     ....
    onItemToggle(oriNode, oriItem, e) {
      debouncedItemToggle(this, oriNode, oriItem, e);
    },

     .....

};

ctonsing avatar Oct 13 '21 15:10 ctonsing

What I am doing is

import _ from 'underscore'

const debouncedItemToggle = _.debounce((model) => {
    // do what you need to do
}, 250);

export default {
     ....
     ....
     onItemToggle(oriNode, model) {
         debouncedItemToggle(model);
     },

     .....
};

how to call method or variable in "debouncedItemToggle" sir? can you give an example? I'm new to vue-jstree

SkyOlredja avatar Aug 08 '22 14:08 SkyOlredja

What I am doing is

import _ from 'underscore'

const debouncedItemToggle = _.debounce((model) => {
    // do what you need to do
}, 250);

export default {
     ....
     ....
     onItemToggle(oriNode, model) {
         debouncedItemToggle(model);
     },

     .....
};

how to call method or variable in "debouncedItemToggle" sir? can you give an example? I'm new to vue-jstree

You can pass in 'this' to the debouncedItemToggle

ventralnet avatar Aug 08 '22 14:08 ventralnet

I have modified this method,delete this code" ,this.onItemToggle(this,this.model)",and it worked ;I don't know whether there will be other side effects. handleItemToggle: function(e) { this.isFolder && (this.model.opened = !this.model.opened) },

renqWork avatar Aug 15 '23 02:08 renqWork

@renqWork good job man 🥳 Please open a PR and notify the Author. After your fix is merged to the main branch and published, close this issue.

Tzahile avatar Aug 27 '23 21:08 Tzahile