I have a custom field to which I pass the image url of another field in the blueprint
image: "{{ page.content.image.toFile().url }}"
In my custom field values I output this query on the backend side
'image' => function ($image = null) {
return $this->model->toSafeString($image);
}
In my vue component, the value is available to me as prop. This all works perfectly during initialisation. But how do I keep this value up to date when the image field changes?
So far I listen to the event model.update to get the new value via the API. The disadvantage, however, is that I have to specify which field I want to read.
Is there a way to create a binding to the value from the blueprint
this.$api.get(this.$view.path)
.then(response => {
this.image = response.content.image[0].url;
})
.catch(error => {
console.log('error', error)
});
});
I have discovered a second problem. As soon as an input $emit takes place, the image property, which was reassigned by the API call, is reset to the old url of the initialisation.
This certainly has to do with vue’s reactive system. Where does the old image property come from? Is it requested again from the backend after the $emit?
Vue doesn’t allow you to mutate props - or technically it does sometimes, but then you run into problems like those described. So in your case, instead of passing the initial image
as a prop, you might consider loading the initial value from the API when the field is mounted.
Another problem you’re facing is that in Kirby 3 and 4, unsaved changes live in the browser’s localStorage. Until the changes are saved, the backend doesn’t know the unsaved value, so if you call page.content.image.toFile().url
again on the backend, it won’t be able to use that unsaved content. Instead, you should probably always read the value of the other field from the Panel content store and send it to your custom API point to resolve to a file object and full url to return to your field.
Ok, I see, if the data flow is from top to bottom, the props are immutable.
Does that mean that it only makes sense to pass the name of the field in the blueprint and query the data via the API in the component? A custom endpoint is a good idea in this case.
How do I access the panel content store?
We don’t have good docs around that yet, but it’s this.$store
in components ,e.g.
this.$store.getters["content/values"]()
for