This is one of those ubiquitous things (like pagination) without a really good canonical example. Here are a few cases that come to mind. I’m not saying all of these are good options, I’m trying to show different approaches that come to my mind.
Option 1 - create the modal view manually
User clicks on a button and a modal is supposed to appear
showDeleteConfirmationModal: function(user) {
modal = Ember.View.create({
templateName: "something",
controller: this.controller,
content: user,
popupHide: function() {
this.remove();
}
}).appendTo('body');
}
This isn’t really nice, since the modal isn’t a self-contained thing, we kind of have to hack the view’s controller and content and manually append it to the body.
Option 2 - create the thing before hand and display it by triggering an action
We could also render all the modals that could appear on the page by doing something like
{{render "confirmation_modal"}}
and then the action handler might look something like this
App.SomeController = Ember.Controller.extend({
needs: "confirmation_modal",
showDeleteConfirmationModal: function() {
this.get("controllers.confirmation_modal").show();
}
});
Option 3 - global binding to display the modal
This is somewhat similar to the previous example, we would pre-render the modal, but only display it based on a binding
{{#if App.confirmationModal}}
{{render "confirmation_modal"}} // rendered in the application.hbs
{{/if}}
and the action handler would just change the global state that triggers the modal
showDeleteConfirmationModal: function() {
App.set("confirmationModal", true);
}
Option 4 - transition to a new substate which renders the modal in an outlet
There’s not much really to show here. Whenever we want to display the modal view we would transition into a substate which would render the modal.
showDeleteConfirmationModal: function() {
this.transitionToRoute("something.confirmation", this.get("content"));
}
Option 5 - local binding
We could do something similar to option 3 but instead render the modals only on the page on which they belong. Other than that, this is basically identical.
Conclusion
In retrospective after writing this, I’m not sure if I like any of these options
- probably good enough for simple things, but it forces us to put all the logic in the view
- what happens here if we can’t get to the correct instance via needs?
- making every single modal global in the application feels wrong
- this could work for fullscreen modals, but what about simple popovers?
- what if we want to pass in a specific context when displaying the modal?
Personally I’ve done mostly 1., but I’m not happy about it. I’d love to hear how other people are solving this, and if possible we could come up with a canonical example that could make it into the documentation (maybe?)