How can Blaze have singleton templates?

tl;dr There needs to be exactly one rendered instance of a particular template so long as any parent template needs it. How would you go about achieving this?


Why?
There are a number of jQuery UI dialogs used to edit complex property objects in the application – one dialog per type/class. Each dialog is in its own Blaze template. There is now a case when both a parent object and a child object can both have a complex property of the same type, thus the parent view template then includes the child view template and both of those templates include their own instance/copy of the template with the jQuery UI dialog editor template (which causes problems: duplicate DOM element IDs, etc.). If the parent is of a different type or if that particular child property is empty/undefined then this doesn’t happen. Fortunately, there is no dialog recursion possible (i.e. none of the complex properties can possibly have a child property of an ancestor’s type).


Thoughts:

  • All such dialog templates can be included in the root view and only in the root view template. However, that leaves potentially a dozen-plus dialogs sitting around unused in the DOM and obfuscates why these dialogs are necessary (which templates use them).

    • There can be an app/window -level ReactiveVar maintaining a running count of dialogs that must be available. This alleviates the excess-dialogs issue and at least leaves a code mark on the template actually demanding access to the singleton dialog, but maintaining client state about what dialogs need to be available seems like a bit much. I don’t think that the client root should have to know/hold what dialogs its children templates cumulatively need.
  • I was trying to think through and write a singleton template wrapper template (use Template.dynamic and render only if there isn’t one), but have not gotten that working.

  • I’ve considered trying to create an editor dialog factory (keep 1 “extra” empty dialog around and dynamically populate its body with the correct form on open), but not attempted that yet.

  • There is probably some kind of a solution using template UUIDs and a factory pattern to turn out unique editor dialogs, but that feels wasteful and unnecessarily complex.

Simplest, as I see it, would be to use a session variable

onCreated:

If (Session.get(mySingletonId) stopThisThing
else set the var and let it render

onDestroyed:
Clear the session variable

Do you know how to “stopThisThing” in onCreated (preferred)? Is it possible to essentially cancel a template from within its onCreated? I have not managed to edit the template instance object to assign a new Mongo.ObjectID() to each.

I’ve written my own Modal-Master package for Meteor(close to release).

I dynamically generate modal content template through a dynamic Sessionvar. This means only one modal, and it can load any template.

On modal close I destroy/reset the content template on the modal (hook into boostrap modal method).

1 Like