diff --git a/docs/stacks/vue/layers/viewmodels.md b/docs/stacks/vue/layers/viewmodels.md index 303dd1e04..6b01f8b84 100644 --- a/docs/stacks/vue/layers/viewmodels.md +++ b/docs/stacks/vue/layers/viewmodels.md @@ -415,6 +415,22 @@ type AutoLoadOptions = Manually turns off auto-loading of the instance. +### Auto-save + + + + +Enables auto-save for the items in the list, propagating to new items as they're added or loaded. See [ViewModel auto-save documentation](#member-autosave) for more details. + + + + +Turns off auto-saving of the items in the list, and turns of propagation of auto-save to any future items if auto-save was previously turned on for the list. Only affects items that are currently in the list's `$items`. + ### Generated Members diff --git a/src/coalesce-vue-vuetify2/src/components/admin/c-admin-table.vue b/src/coalesce-vue-vuetify2/src/components/admin/c-admin-table.vue index 94089dc95..8737dfdd3 100644 --- a/src/coalesce-vue-vuetify2/src/components/admin/c-admin-table.vue +++ b/src/coalesce-vue-vuetify2/src/components/admin/c-admin-table.vue @@ -237,15 +237,15 @@ export default defineComponent({ } this.$watch( - () => [this.editable, ...this.viewModel.$items.map((i) => i.$stableId)], - () => { - if (this.editable) { - for (const item of this.viewModel.$items) { - item.$startAutoSave(this, { wait: 100 }); - } + () => this.editable, + (editable) => { + if (editable && !this.viewModel.$isAutoSaveEnabled) { + this.viewModel.$startAutoSave(this, { wait: 100 }); + } else if (!editable && this.viewModel.$isAutoSaveEnabled) { + this.viewModel.$stopAutoSave(); } }, - { immediate: true, deep: true } + { immediate: true } ); this.viewModel.$load.setConcurrency("debounce"); diff --git a/src/coalesce-vue-vuetify3/src/components/admin/c-admin-table.vue b/src/coalesce-vue-vuetify3/src/components/admin/c-admin-table.vue index 2cc651e84..a003a5de5 100644 --- a/src/coalesce-vue-vuetify3/src/components/admin/c-admin-table.vue +++ b/src/coalesce-vue-vuetify3/src/components/admin/c-admin-table.vue @@ -234,15 +234,15 @@ export default defineComponent({ } this.$watch( - () => [this.editable, ...this.viewModel.$items.map((i) => i.$stableId)], - () => { - if (this.editable) { - for (const item of this.viewModel.$items) { - item.$startAutoSave(this, { wait: 100 }); - } + () => this.editable, + (editable) => { + if (editable && !this.viewModel.$isAutoSaveEnabled) { + this.viewModel.$startAutoSave(this, { wait: 100 }); + } else if (!editable) { + this.viewModel.$stopAutoSave(); } }, - { immediate: true, deep: true } + { immediate: true } ); this.viewModel.$load.setConcurrency("debounce"); diff --git a/src/coalesce-vue/src/viewmodel.ts b/src/coalesce-vue/src/viewmodel.ts index 201e8e09a..69da15909 100644 --- a/src/coalesce-vue/src/viewmodel.ts +++ b/src/coalesce-vue/src/viewmodel.ts @@ -1077,7 +1077,7 @@ export abstract class ViewModel< /** Stops auto-saving if it is currently enabled. */ public $stopAutoSave() { - this._autoSaveState?.cleanup!(); + this._autoSaveState?.cleanup?.(); } /** Returns true if auto-saving is currently enabled. */ @@ -1418,6 +1418,68 @@ export abstract class ListViewModel< this._autoLoadState.cleanup?.(); } + /** @internal Internal autosave state */ + private _autoSaveState = new AutoCallState(); + + /** + * Enables auto save for the items in the list. + * Only usable from Vue setup() or