Frontmatter
| id | 4676 |
| title | component.Base: afterSetVdom() => add a check in case no vnode is there yet |
| state | Closed |
| labels | enhancementstale |
| assignees | tobiu |
| createdAt | Aug 8, 2023, 9:02 PM |
| updatedAt | Sep 13, 2024, 4:29 AM |
| githubUrl | https://github.com/neomjs/neo/issues/4676 |
| author | tobiu |
| commentsCount | 5 |
| parentIssue | null |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Sep 13, 2024, 4:29 AM |
component.Base: afterSetVdom() => add a check in case no vnode is there yet

this one can break card layouts & key navs. reverting it for now. needs more testing.

found a way

more input on the topic:
afterSetVdom(value, oldValue) {
let me = this,
app = Neo.apps[me.appName],
vdom = value,
isParentVdomUpdating, listenerId;
// It is important to keep the vdom tree stable to ensure that containers do not lose the references to their
// child vdom trees. The if case should not happen, but in case it does, keeping the reference and merging
// the content over seems to be the best strategy
if (me._vdom !== vdom) {
Logger.warn('vdom got replaced for: ' + me.id + '. Copying the content into the reference holder object');
Object.keys(me._vdom).forEach(key => {
delete me._vdom[key]
});
vdom = Object.assign(me._vdom, vdom)
}
if (!me.needsParentUpdate()) {
if (me.silentVdomUpdate) {
me.needsVdomUpdate = true
} else {
isParentVdomUpdating = me.isParentVdomUpdating();
if (!me.mounted && me.isConstructed && !me.hasRenderingListener && app?.rendering === true) {
me.hasRenderingListener = true;
listenerId = app.on('mounted', () => {
app.un('mounted', listenerId);
setTimeout(() => {
me.vnode && me.updateVdom(me.vdom, me.vnode)
}, 50)
})
} else if (me.mounted && me.vnode && !isParentVdomUpdating) {
me.updateVdom(vdom, me.vnode)
} else if (!me.vnode && !isParentVdomUpdating && me.isConstructed) {
console.log(this.id, me.mounted, me.rendering, app?.rendering);
me.needsVdomUpdate = true
}
}
} else {
me.needsVdomUpdate = false
}
me.hasUnmountedVdomChanges = !me.mounted && me.hasBeenMounted
}
adding a check => else if (!vnode)
and then:
afterSetMounted(value, oldValue) {
if (oldValue !== undefined) {
let me = this;
if (value) {
me.hasBeenMounted = true;
if (me.domListeners?.length > 0) {
// todo: the main thread reply of mount arrives after pushing the task into the queue which does not ensure the dom is mounted
setTimeout(() => {
DomEventManager.mountDomListeners(me)
}, 100)
}
me.fire('mounted', me.id);
this.needsVdomUpdate && this.update()
}
}
}
=> this.needsVdomUpdate && this.update()
does fix an edge case bug inside our client app, when we open a card layout with an lazy loaded active card, destroying the view & afterwards re-creating it, but this has severe side effects.
e.g. for component.Gallery inside our covid app, a parent container will get the needsVdomUpdate state and this will never get cleared again. neither the parent container nor any of its parent are inside an update cycle.
this one needs a closer look and goes pretty deep into component.Base.
@github-actions - 2024-08-29T02:26:49Z
This issue is stale because it has been open for 90 days with no activity.
- 2024-08-29T02:26:50Z @github-actions added the
stalelabel
@github-actions - 2024-09-13T02:29:19Z
This issue was closed because it has been inactive for 14 days since being marked as stale.
- 2024-09-13T02:29:19Z @github-actions closed this issue
since this means, that no update cycle is running, we need to do this inside
afterSetMounted().