Skip to content

Commit

Permalink
fix: c-select getting stuck on defineModel local values
Browse files Browse the repository at this point in the history
  • Loading branch information
ascott18 committed Mar 20, 2024
1 parent c3b256e commit aee7964
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 21 deletions.
26 changes: 21 additions & 5 deletions playground/Coalesce.Web.Vue3/src/components/test-setup.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
<template>
<span>123</span>
<div>
<span>123</span>
<v-btn @click="reset">Reset</v-btn>
<v-btn @click="person.companyId = null">Reset direct</v-btn>

<c-select :model="person" for="company"> </c-select>

<v-btn @click="person.birthDate = null">Reset direct</v-btn>
<c-input :model="person" for="birthDate"> </c-input>
</div>
</template>

<script setup lang="ts">
Expand All @@ -11,8 +20,15 @@ import {
} from "@/viewmodels.g";
import { useBindToQueryString } from "coalesce-vue";
import { ref } from "vue";
(() => {
const person = new PersonViewModel();
person.arbitraryCollectionOfStrings = ["asdf"];
})();
import { useRouter } from "vue-router";
const router = useRouter();
const person = new PersonViewModel();
person.arbitraryCollectionOfStrings = ["asdf"];
useBindToQueryString(person, "companyId", "companyId", parseInt, "replace");
function reset() {
router.replace({ query: {} });
}
</script>
40 changes: 24 additions & 16 deletions src/coalesce-vue-vuetify3/src/components/input/c-select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,12 @@ const props = withDefaults(
reloadOnOpen?: boolean;
params?: ListParameters;
// DONT use defineModel for these. We don't want to capture local state if the parent isn't binding it
// since we have 4 different binding sources in this component, we'll get stuck on the values of the ones that aren't used.
keyValue?: any;
objectValue?: Model;
modelValue?: any;
/** Response caching configuration for the `/get` and `/list` API calls made by the component.
* See https://intellitect.github.io/Coalesce/stacks/vue/layers/api-clients.html#response-caching. */
cache?: ResponseCachingConfiguration | boolean;
Expand All @@ -278,9 +284,11 @@ const props = withDefaults(
{ openOnClear: true }
);
const modelValue = defineModel();
const keyValue = defineModel("keyValue");
const objectValue = defineModel<Model | null>("objectValue");
const emit = defineEmits<{
"update:keyValue": [value: any];
"update:objectValue": [value: any];
"update:modelValue": [value: any];
}>();
const mainInputRef = ref<HTMLInputElement>();
const listRef = ref<ComponentPublicInstance>();
Expand Down Expand Up @@ -364,10 +372,10 @@ const primaryBindKind = computed(() => {
return "key";
}
if (valueMeta.value.type == "model") {
if (typeof modelValue.value != "object" && modelValue.value !== undefined) {
if (typeof props.modelValue != "object" && props.modelValue !== undefined) {
throw (
"Expected a model object to be bound to modelValue, but received a " +
typeof modelValue.value
typeof props.modelValue
);
}
return "model";
Expand All @@ -390,8 +398,8 @@ const modelObjectMeta = computed(() => {
/** The effective object (whose type is described by `modelObjectMeta`) that has been provided to the component. */
const internalModelValue = computed(() => {
if (objectValue.value) {
return objectValue.value;
if (props.objectValue) {
return props.objectValue;
}
if (
valueOwner.value &&
Expand All @@ -401,8 +409,8 @@ const internalModelValue = computed(() => {
return valueOwner.value[modelObjectProp.value.name];
}
if (modelValue.value && primaryBindKind.value == "model") {
return modelValue.value;
if (props.modelValue && primaryBindKind.value == "model") {
return props.modelValue;
}
if (internalKeyValue.value) {
Expand Down Expand Up @@ -459,12 +467,12 @@ const internalModelValue = computed(() => {
/** The effective key (whose type is described by `modelObjectMeta`) that has been provided to the component. */
const internalKeyValue = computed(() => {
let value: any;
if (keyValue.value) {
value = keyValue.value;
if (props.keyValue) {
value = props.keyValue;
} else if (valueOwner.value && modelKeyProp.value) {
value = valueOwner.value[modelKeyProp.value.name];
} else if (modelValue.value && primaryBindKind.value == "key") {
value = modelValue.value;
} else if (props.modelValue && primaryBindKind.value == "key") {
value = props.modelValue;
} else {
value = null;
}
Expand Down Expand Up @@ -550,9 +558,9 @@ function onInput(
}
}
modelValue.value = primaryBindKind.value == "key" ? key : value;
objectValue.value = value;
keyValue.value = key;
emit("update:modelValue", primaryBindKind.value == "key" ? key : value);
emit("update:objectValue", value);
emit("update:keyValue", key);
pendingSelection.value = value ? listItems.value.indexOf(value) : 0;
// When the input value is cleared, re-focus the dropdown
Expand Down

0 comments on commit aee7964

Please sign in to comment.