Reputation: 5363
I have a form for updating document entity.
The document entity consists of list of employees (which is an array of objects) and each employee has a post which is just a string.
I have a dropdown (kind of wrapper for vue-multiselect) which accepts the array of employees and syncs selected employee to a selectedEmployee
variable in data()
.
And also I have a watcher for selectedEmployee
which sets the post
input automatically when an employee is selected in the dropdown.
So, when creating a document in the form everything's fine, however, when I update the document, then I fetch existing document from server, set selectedEmployee
and set employee's post. But, the document also keeps employee's post, so the first time when I open document's form in order to update it, I don't want to automatically update document's post. I want it to be updated only when user actually selects employee himself.
But the watcher gets called the first time too.
So, imagine we have John Doe and his a manager. When I create the document, I change his post to designer. Then, I open up the document form in order to update it, and I should see that for this specific document John Doe's post is "designer", but the watcher gets called and returns the post to manager.
I tried to make a fake variable in data(), like doneFetching
, but it works only if I update this var directly in watcher, which looks quite dangerous, plus, in other entities I have many different kinds of selected employees, so making tons of fake flags is not an option.
Here is real code sample (employee = representative in my case):
selectedApproveRepresentative(representative) {
if (!representative) {
this.memoData.approve_representative_id = null
return
}
this.memoData.approve_representative_id = representative.id
// Here is temporary solution, but I have many watchers for many different kinds of employees. If I move the doneFetching flag after I initialized the form, it'll be set to true, and only after that the watcher will be called
if (this.mode === 'update' && !this.doneFetching) {
this.doneFetching = true
return
}
// In normal case a representative might have or have not post, so depending on this case we set it to be empty or filled. But this should not be called the first time I open the form
this.memoData.approve_representative_post_dative_case =
representative.post_dative_case ?
representative.post_dative_case : ''
},
Here is where I initialize data:
created() {
if (this.memo) {
this.memoData = _.cloneDeep(this.memo)
this.selectedApproveRepresentative = _.cloneDeep(this.memo.approve_representative)
}
},
Upvotes: 1
Views: 1052
Reputation: 3928
as I understood, your problem is the watcher executed when you init the component. Have you tried setting the immediate property of the watcher to false?
Not everybody knows that the watchers can be defined in different ways.
watchers: {
propertyToWatch() { //code... }
}
watchers: {
propertyToWatch: 'nameOfAfunctionDefinedInMethodsSection'
}
This one is the most descriptive way of declaring a watcher. You write it as an object with a handler property (it can be the name of a function passed as string as above), and other properties like deep
to watch nested properties of an object, or in your case immediate
which tells to the watcher if the should run immediately when the component is mounted.
watchers: {
propertyToWatch: {
immediate: false,
handler: function() { //code.. }
}
}
Upvotes: 1