refactor: refs #7679 better way to update model #581

Merged
alexm merged 2 commits from 7679-vnLocation_improve into master 2024-08-01 08:06:20 +00:00
6 changed files with 56 additions and 47 deletions

View File

@ -19,8 +19,8 @@ const cityFormData = reactive({
const provincesOptions = ref([]); const provincesOptions = ref([]);
const onDataSaved = (dataSaved) => { const onDataSaved = (...args) => {
emit('onDataSaved', dataSaved); emit('onDataSaved', ...args);
}; };
</script> </script>
@ -36,7 +36,7 @@ const onDataSaved = (dataSaved) => {
:form-initial-data="cityFormData" :form-initial-data="cityFormData"
url-create="towns" url-create="towns"
model="city" model="city"
@on-data-saved="onDataSaved($event)" @on-data-saved="onDataSaved"
> >
<template #form-inputs="{ data, validate }"> <template #form-inputs="{ data, validate }">
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">

View File

@ -22,20 +22,17 @@ const postcodeFormData = reactive({
townFk: null, townFk: null,
}); });
const townsFetchDataRef = ref(null);
const provincesFetchDataRef = ref(null); const provincesFetchDataRef = ref(null);
const countriesOptions = ref([]); const countriesOptions = ref([]);
const provincesOptions = ref([]); const provincesOptions = ref([]);
const townsLocationOptions = ref([]); const town = ref({});
function onDataSaved(formData) { function onDataSaved(formData) {
const newPostcode = { const newPostcode = {
...formData, ...formData,
}; };
const townObject = townsLocationOptions.value.find( newPostcode.town = town.value.name;
({ id }) => id === formData.townFk newPostcode.townFk = town.value.id;
);
newPostcode.town = townObject?.name;
const provinceObject = provincesOptions.value.find( const provinceObject = provincesOptions.value.find(
({ id }) => id === formData.provinceFk ({ id }) => id === formData.provinceFk
); );
@ -47,25 +44,23 @@ function onDataSaved(formData) {
emit('onDataSaved', newPostcode); emit('onDataSaved', newPostcode);
} }
async function onCityCreated({ name, provinceFk }, formData) { async function onCityCreated(newTown, formData) {
await townsFetchDataRef.value.fetch(); newTown.province = provincesOptions.value.find(
await provincesFetchDataRef.value.fetch(); (province) => province.id === newTown.provinceFk
formData.townFk = townsLocationOptions.value.find((town) => town.name === name).id; );
formData.provinceFk = provinceFk; formData.townFk = newTown;
formData.countryFk = provincesOptions.value.find( setTown(newTown, formData);
(province) => province.id === provinceFk
).countryFk;
} }
function setTown(id, data) { function setTown(newTown, data) {
const newTown = townsLocationOptions.value.find((town) => town.id == id);
if (!newTown) return; if (!newTown) return;
town.value = newTown;
data.provinceFk = newTown.provinceFk; data.provinceFk = newTown.provinceFk;
data.countryFk = newTown.province.countryFk; data.countryFk = newTown.province.countryFk;
} }
function setProvince(id, data) { async function setProvince(id, data) {
await provincesFetchDataRef.value.fetch();
const newProvince = provincesOptions.value.find((province) => province.id == id); const newProvince = provincesOptions.value.find((province) => province.id == id);
if (!newProvince) return; if (!newProvince) return;
@ -74,18 +69,11 @@ function setProvince(id, data) {
</script> </script>
<template> <template>
<FetchData
ref="townsFetchDataRef"
@on-fetch="(data) => (townsLocationOptions = data)"
auto-load
url="Towns/location"
/>
<FetchData <FetchData
ref="provincesFetchDataRef" ref="provincesFetchDataRef"
:filter="{ include: { relation: 'country' } }"
@on-fetch="(data) => (provincesOptions = data)" @on-fetch="(data) => (provincesOptions = data)"
auto-load auto-load
url="Provinces" url="Provinces/location"
/> />
<FetchData <FetchData
@on-fetch="(data) => (countriesOptions = data)" @on-fetch="(data) => (countriesOptions = data)"
@ -98,6 +86,7 @@ function setProvince(id, data) {
:title="t('New postcode')" :title="t('New postcode')"
:subtitle="t('Please, ensure you put the correct data!')" :subtitle="t('Please, ensure you put the correct data!')"
:form-initial-data="postcodeFormData" :form-initial-data="postcodeFormData"
:mapper="(data) => (data.townFk = data.townFk.id) && data"
@on-data-saved="onDataSaved" @on-data-saved="onDataSaved"
> >
<template #form-inputs="{ data, validate }"> <template #form-inputs="{ data, validate }">
@ -109,14 +98,15 @@ function setProvince(id, data) {
/> />
<VnSelectDialog <VnSelectDialog
:label="t('City')" :label="t('City')"
:options="townsLocationOptions" url="Towns/location"
@update:model-value="(value) => setTown(value, data)" @update:model-value="(value) => setTown(value, data)"
v-model="data.townFk" v-model="data.townFk"
hide-selected
option-label="name" option-label="name"
option-value="id" option-value="id"
:rules="validate('postcode.city')" :rules="validate('postcode.city')"
:roles-allowed-to-create="['deliveryAssistant']" :roles-allowed-to-create="['deliveryAssistant']"
:emit-value="false"
clearable
> >
<template #option="{ itemProps, opt }"> <template #option="{ itemProps, opt }">
<QItem v-bind="itemProps"> <QItem v-bind="itemProps">
@ -130,7 +120,12 @@ function setProvince(id, data) {
</QItem> </QItem>
</template> </template>
<template #form> <template #form>
<CreateNewCityForm @on-data-saved="onCityCreated($event, data)" /> <CreateNewCityForm
@on-data-saved="
(_, requestResponse) =>
onCityCreated(requestResponse, data)
"
/>
</template> </template>
</VnSelectDialog> </VnSelectDialog>
</VnRow> </VnRow>

View File

@ -20,6 +20,9 @@ const provinceFormData = reactive({
const autonomiesOptions = ref([]); const autonomiesOptions = ref([]);
const onDataSaved = (dataSaved, requestResponse) => { const onDataSaved = (dataSaved, requestResponse) => {
requestResponse.autonomy = autonomiesOptions.value.find(
(autonomy) => autonomy.id == requestResponse.autonomyFk
);
emit('onDataSaved', dataSaved, requestResponse); emit('onDataSaved', dataSaved, requestResponse);
}; };
</script> </script>
@ -28,7 +31,7 @@ const onDataSaved = (dataSaved, requestResponse) => {
<FetchData <FetchData
@on-fetch="(data) => (autonomiesOptions = data)" @on-fetch="(data) => (autonomiesOptions = data)"
auto-load auto-load
url="Autonomies" url="Autonomies/location"
/> />
<FormModelPopup <FormModelPopup
:title="t('New province')" :title="t('New province')"
@ -53,7 +56,16 @@ const onDataSaved = (dataSaved, requestResponse) => {
option-value="id" option-value="id"
v-model="data.autonomyFk" v-model="data.autonomyFk"
:rules="validate('province.autonomyFk')" :rules="validate('province.autonomyFk')"
/> >
<template #option="{ itemProps, opt }">
<QItem v-bind="itemProps">
<QItemSection>
<QItemLabel>{{ opt.name }}</QItemLabel>
<QItemLabel caption> {{ opt.country.name }} </QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
</VnRow> </VnRow>
</template> </template>
</FormModelPopup> </FormModelPopup>

View File

@ -7,6 +7,7 @@ import VnSelectDialog from 'components/common/VnSelectDialog.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import CreateNewProvinceForm from './CreateNewProvinceForm.vue'; import CreateNewProvinceForm from './CreateNewProvinceForm.vue';
const emit = defineEmits(['onProvinceCreated']);
const provinceFk = defineModel({ type: Number }); const provinceFk = defineModel({ type: Number });
watch(provinceFk, async () => await provincesFetchDataRef.value.fetch()); watch(provinceFk, async () => await provincesFetchDataRef.value.fetch());
@ -16,9 +17,10 @@ const { t } = useI18n();
const provincesOptions = ref(); const provincesOptions = ref();
const provincesFetchDataRef = ref(); const provincesFetchDataRef = ref();
async function onProvinceCreated(_, { id }) { async function onProvinceCreated(_, data) {
await provincesFetchDataRef.value.fetch(); await provincesFetchDataRef.value.fetch();
provinceFk.value = id; provinceFk.value = data.id;
emit('onProvinceCreated', data);
} }
</script> </script>

View File

@ -23,8 +23,8 @@ function showLabel(data) {
:input-debounce="300" :input-debounce="300"
:class="{ required: $attrs.required }" :class="{ required: $attrs.required }"
v-bind="$attrs" v-bind="$attrs"
@update:model-value="(_, object) => (value = object)"
clearable clearable
:emit-value="false"
> >
<template #form> <template #form>
<CreateNewPostcode @on-data-saved="(newValue) => (value = newValue)" /> <CreateNewPostcode @on-data-saved="(newValue) => (value = newValue)" />

View File

@ -88,11 +88,7 @@ const value = computed({
}, },
set(value) { set(value) {
setOptions(myOptionsOriginal.value); setOptions(myOptionsOriginal.value);
emit( emit('update:modelValue', value);
Review

Esto lo puse yo para el VnLocation aposta, ya no hace falta

Esto lo puse yo para el VnLocation aposta, ya no hace falta
Review

Por eso en VnLocation has puesto emit-value= false?

Por eso en VnLocation has puesto emit-value= false?
'update:modelValue',
value,
value && myOptions.value.find((o) => o[optionValue.value] == value)
);
}, },
}); });
@ -187,6 +183,10 @@ async function filterHandler(val, update) {
} }
); );
} }
function nullishToTrue(value) {
return value ?? true;
}
</script> </script>
<template> <template>
@ -205,12 +205,12 @@ async function filterHandler(val, update) {
:option-label="optionLabel" :option-label="optionLabel"

Podrías hacer una pequeña fn para no tener que escribir cada vez $attrs[x] ?? true.

Podrías hacer una pequeña fn para no tener que escribir cada vez $attrs[x] ?? true.
:option-value="optionValue" :option-value="optionValue"
v-bind="$attrs" v-bind="$attrs"
emit-value
map-options
use-input
@filter="filterHandler" @filter="filterHandler"
hide-selected :emit-value="nullishToTrue($attrs['emit-value'])"
fill-input :map-options="nullishToTrue($attrs['map-options'])"
:use-input="nullishToTrue($attrs['use-input'])"
:hide-selected="nullishToTrue($attrs['hide-selected'])"
:fill-input="nullishToTrue($attrs['fill-input'])"
ref="vnSelectRef" ref="vnSelectRef"
lazy-rules lazy-rules
:class="{ required: $attrs.required }" :class="{ required: $attrs.required }"