diff --git a/bundles/org.openhab.ui/doc/components/oh-repeater.md b/bundles/org.openhab.ui/doc/components/oh-repeater.md
index 7a406f122a..b246d58c95 100644
--- a/bundles/org.openhab.ui/doc/components/oh-repeater.md
+++ b/bundles/org.openhab.ui/doc/components/oh-repeater.md
@@ -122,6 +122,11 @@ Iterate over an array and repeat the children components in the default slot
Render all children directly under the repeater's parent, without any container
+
+
+ For loaded sources (e.g. with Items or rules), the source array will be cached and not refreshed on page updates
+
+
diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/widgets/system/repeater.js b/bundles/org.openhab.ui/web/src/assets/definitions/widgets/system/repeater.js
index 8d650f5282..bb156793f6 100644
--- a/bundles/org.openhab.ui/web/src/assets/definitions/widgets/system/repeater.js
+++ b/bundles/org.openhab.ui/web/src/assets/definitions/widgets/system/repeater.js
@@ -27,5 +27,6 @@ export default () => [
pb('listContainer', 'List container', 'The child components will be wrapped in a ul
HTML elements instead of a div
'),
pt('containerClasses', 'Classes of the container', 'Add these CSS classes to the container'),
pt('containerStyle', 'Styles of the container', 'Add these CSS styles to the container'),
- pb('fragment', 'No container (fragment)', 'Render all children directly under the repeater\'s parent, without any container')
+ pb('fragment', 'No container (fragment)', 'Render all children directly under the repeater\'s parent, without any container'),
+ pb('cacheSource', 'Suppress source refresh', 'For loaded sources (e.g. with Items or rules), the source array will be cached and not refreshed on page updates')
]
diff --git a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-repeater.vue b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-repeater.vue
index 4997292258..6a189c5f81 100644
--- a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-repeater.vue
+++ b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-repeater.vue
@@ -1,4 +1,4 @@
-
+
@@ -24,13 +24,9 @@ export default {
widget: OhRepeaterDefinition,
data () {
return {
- ready: false,
- loadedSource: null
+ sourceCache: null
}
},
- created () {
- this.load()
- },
computed: {
childrenContexts () {
const iterationContext = (ctx, el, idx, source) => {
@@ -75,42 +71,37 @@ export default {
}
return contexts
- },
- source () {
- if (this.loadedSource !== null) return this.loadedSource
- switch (this.config.sourceType) {
- case 'range':
- const start = this.config.rangeStart || 0
- const stop = this.config.rangeStop || 10
- const step = this.config.rangeStep || 1
- return Array(Math.ceil((stop + 1 - start) / step)).fill(start).map((x, y) => x + y * step)
- default:
- return this.config.in
- }
}
},
- methods: {
- load () {
- let loadPromise
- if (this.config.sourceType === 'itemsWithTags' && this.config.itemTags) {
- loadPromise = this.$oh.api.get('/rest/items?metadata=' + this.config.fetchMetadata + '&tags=' + this.config.itemTags).then((d) => Promise.resolve(d.sort(compareItems)))
+ asyncComputed: {
+ source () {
+ if (this.config.cacheSource && this.sourceCache) return this.sourceCache
+ let sourceResult
+ if (this.config.sourceType === 'range') {
+ const start = this.config.rangeStart || 0
+ const stop = this.config.rangeStop || 10
+ const step = this.config.rangeStep || 1
+ sourceResult = Promise.resolve(Array(Math.ceil((stop + 1 - start) / step)).fill(start).map((x, y) => x + y * step))
+ } else if (this.config.sourceType === 'itemsWithTags' && this.config.itemTags) {
+ sourceResult = this.$oh.api.get('/rest/items?metadata=' + this.config.fetchMetadata + '&tags=' + this.config.itemTags).then((d) => Promise.resolve(d.sort(compareItems)))
+ this.sourceCache = (this.config.cacheSource) ? sourceResult : null
} else if (this.config.sourceType === 'itemsInGroup') {
- loadPromise = this.$oh.api.get('/rest/items/' + this.config.groupItem + '?metadata=' + this.config.fetchMetadata + '&tags=' + this.config.itemTags).then((i) => Promise.resolve(i.members.sort(compareItems)))
+ sourceResult = this.$oh.api.get('/rest/items/' + this.config.groupItem + '?metadata=' + this.config.fetchMetadata + '&tags=' + this.config.itemTags).then((i) => Promise.resolve(i.members.sort(compareItems)))
+ this.sourceCache = (this.config.cacheSource) ? sourceResult : null
} else if (this.config.sourceType === 'itemStateOptions') {
- loadPromise = this.$oh.api.get('/rest/items/' + this.config.itemOptions).then((i) => Promise.resolve((i.stateDescription) ? i.stateDescription.options : []))
+ sourceResult = this.$oh.api.get('/rest/items/' + this.config.itemOptions).then((i) => Promise.resolve((i.stateDescription) ? i.stateDescription.options : []))
+ this.sourceCache = (this.config.cacheSource) ? sourceResult : null
} else if (this.config.sourceType === 'itemCommandOptions') {
- loadPromise = this.$oh.api.get('/rest/items/' + this.config.itemOptions).then((i) => Promise.resolve((i.commandDescription) ? i.commandDescription.commandOptions : []))
+ sourceResult = this.$oh.api.get('/rest/items/' + this.config.itemOptions).then((i) => Promise.resolve((i.commandDescription) ? i.commandDescription.commandOptions : []))
+ this.sourceCache = (this.config.cacheSource) ? sourceResult : null
} else if (this.config.sourceType === 'rulesWithTags' && this.config.ruleTags) {
- loadPromise = this.$oh.api.get('/rest/rules?summary=true' + '&tags=' + this.config.ruleTags).then((r) => Promise.resolve(r.sort(compareRules)))
+ sourceResult = this.$oh.api.get('/rest/rules?summary=true' + '&tags=' + this.config.ruleTags).then((r) => Promise.resolve(r.sort(compareRules)))
+ this.sourceCache = (this.config.cacheSource) ? sourceResult : null
} else {
- this.ready = true
- return
+ sourceResult = Promise.resolve(this.config.in)
}
- loadPromise.then((d) => {
- this.loadedSource = d
- this.ready = true
- })
+ return sourceResult
}
}
}
-
+
\ No newline at end of file