templateInstance.view.template._callbacks.rendered[0].call(templateInstance);
Is there a cleaner way to access the onRendered()
callback (to call it/them manually / to re-run them) given a template instance?
templateInstance.view.template._callbacks.rendered[0].call(templateInstance);
Is there a cleaner way to access the onRendered()
callback (to call it/them manually / to re-run them) given a template instance?
Using this.autorun that is based on reactive variables (ReactiveVar / Session / Collection)
I assume you’re trying to fix problems with someone else’s package, rather than trying to call a onRendered callback that you wrote yourself? Otherwise this seems like a very weird thing to do.
I have a template with jQuery UI widgets which I would like to reuse in other templates, some of which wrap/are jQuery UI dialog widgets. For the widgets to work, the dialog widget must be initialized first. The “obvious” place to put the dialog widget initialization is in the onRendered
of the template containing the uninitialized dialog. The “obvious” place to put the other widget initialization is in the onRendered
of the other template. However, doing this and nothing else, the contained template’s onRendered
gets called first.
My idea of “obvious” might be wrong, but … it’s code which adds GUI functionality to the template as soon as the template is rendered to the window. Where else would the code reasonably go?
onRendered
waits and tries again if it wouldn’t work immediately because the initialization order would be incorrect. This seems like the best option. It keeps the onRendered
code in an onRendered
block, where it belongs semantically. It involves no communication between the dialog and its contents about the state of the dialog (unless you count the implicit “communication” here). And the init-order issue should be “solved” for the template.Template.myTemplate.onRendered(function () {
let templateInstance = this;
if (templateInstance.$('*').parents('.dialog').not(':ui-dialog').length > 0) {
Tracker.afterFlush(() => {
templateInstance.view.template._callbacks.rendered[0].call(templateInstance);
});
return;
}
...
onRendered
callback function inside another function to pass around, but that doesn’t seem like an improvement.Template.myTemplate.onRendered(function () {
let myOnRenderedCallback = function () {
...
};
let templateInstance = this;
if (templateInstance.$('*').parents('.dialog').not(':ui-dialog').length > 0) {
Tracker.afterFlush(() => {
myOnRenderedCallback.call(templateInstance);
});
return;
}
});
appendTo
option” (e.g. Selectmenu appendTo
). But that means remembering / documenting / communicating that all jQuery UI widgets must have their appendTo
option set correctly if the widget is in a template which might wind up in a dialog.templateInstance.$(selector).widget({
appendTo: templateInstance.$('*').first()
...
Having the dialog template force it’s onRendered
to fire before its contents’ onRendered
callbacks might be better, but I couldn’t figure out how that might be accomplished and I’m not sure what other consequences that might incur.
It is possible to write a function to run every time a dialog is initialized to check all of its descendant elements for initialized widgets and updating their appendTo
option to be the dialog unless the appendTo
is already set to a descendant of the dialog getting initialized, but that seems slow and error-prone.