Reputation: 129
I want to be able to call two different methods on a single button click, but I want the methods to run one after the other. Indeed, I have my first method which creates multiple instances of a component and the second one is going to move these instances on my screen. I didn't find a solution to create the instances and move them in a single method so I want to do it that way.
I tried by calling the two methods like this : @click="method1(); method2();"
but the two methods are executed at the same time.
So these are the methods I am dealing with:
modifyLayer(){
console.log(this.selectedLayer)
this.modifyingLayer = this.selectedLayer
var donnéesCouche = this.couche.find(element => element.id == this.modifyingLayer)
this.emplacement=[]
this.emplacement = donnéesCouche.listePositions
},
moveLayer(){
for (var element in this.emplacement){
var toMove=document.getElementById(this.emplacement[element].id)
for (var element in this.emplacement){
toMove.top=this.emplacement[element].x
toMove.left=this.emplacement[element].y
}
}
},
this.emplacement
corresponds to a list of objects like this: {id: ....; x: "...px"; y: "...px"}
and in my HTML, I create instances of my component with a v-for
each element in this.emplacement
Could you help me find a solution, either to call the two methods one after the other or to be able to create instances and move them within the same method?
Thank you for your help!
Upvotes: 1
Views: 666
Reputation: 37763
I want to be able to call two different methods on a single button click, but I want the methods to run one after the other
Well, the handler as @click="method1(); method2();"
indeed runs the methods one after another (1st returns before 2nd starts)
I have my first method which creates multiple instances of a component and the second one is going to move these instances on my screen.
This is little bit unfortunate wording. Your fist method does not create any components directly. It just assigns some data into emplacement
data member and this emplacement
property is used in the template to render some components...
So your problem is not that those methods are not executed one after another (they are), problem is that Vue is using async update queue to update the DOM
So when the modifyLayer()
finishes executing, DOM elements for the emplacement
does not exist yet. The solution is to postpone the moveLayer()
execution using the $nextTick() method
So instead of @click="method1(); method2();"
handler, create a method:
@click="handleClick"
methods: {
handleClick() {
this.modifyLayer()
this.$nextTick(this.moveLayer)
}
}
Note: even tho I do not understand why you rendering 1st and moving later instead of rendering everything in one go at correct possition. Something like document.getElementById
is not needed in Vue in most cases....
Upvotes: 1
Reputation: 13
Can't you do something like that : @click="methods()"
And then declare :
async methods{
await this.methods1()
this.methods2()
}
Upvotes: 0
Reputation: 2412
You can simply call the second method from the first one, and call the first method on button click. @click="modifyLayer()"
modifyLayer(){
console.log(this.selectedLayer)
this.modifyingLayer = this.selectedLayer
var donnéesCouche = this.couche.find(element => element.id == this.modifyingLayer)
this.emplacement=[]
this.emplacement = donnéesCouche.listePositions
this.moveLayer(); // calling the second method from the first
},
moveLayer(){
for (var element in this.emplacement){
var toMove=document.getElementById(this.emplacement[element].id)
for (var element in this.emplacement){
toMove.top=this.emplacement[element].x
toMove.left=this.emplacement[element].y
}
}
Upvotes: 0