There are lots of ways to do this and some plugins out there (eg aexmachina’s ember-notify and poteto’s ember-cli-flash) but here is my take
Use a simple array controller to keep track of the current messages, a model to hold the message and what type of alert it is, a view with an action to remove the alert and a template to show it on the page.
The page needs a template containing the flash messages.
<script type="text/x-handlebars">
{{#each flashMessage in controllers.flash.content}}
{{view "flash" contentBinding="flashMessage"}}
{{/each}}
</script>
It also needs a template for the flash message.
<script type='text/x-handlebars' id='flash'>
{{#if flashMessage.isNotice}}
<div class="alert notice">
{{flashMessage.message}}
<button type="button" class="right" {{action "click" flashMessage target=view}}><span>×</span></button>
</div>
{{/if}}
{{#if flashMessage.isSuccess}}
<div class="alert success">
<button type="button" class="right" {{action "click" flashMessage target=view}}><span>×</span></button>
{{flashMessage.message}}
</div>
{{/if}}
{{#if flashMessage.isError}}
<div class="alert error">
<button type="button" class="right" {{action "click" flashMessage target=view}}><span>×</span></button>
{{flashMessage.message}}
</div>
{{/if}}
</script>
We need a controller to keep track of all the flash messages
App.FlashController = Ember.ArrayController.extend({
createFlash: function(options) {
if (options.type !== null && options.message !== null) {
this.pushObject(this.get('store').createRecord(
"flashMessage", {
type: options.type,
message: options.message
}
));
}
}
});
We also need model for a flash message.
App.FlashMessage = DS.Model.extend({
type: DS.attr('string'),
message: DS.attr('string'),
isNotice: function() {
return this.get("type") === "notice";
}.property("type"),
isSuccess: function() {
return this.get("type") === "success";
}.property("type"),
isError: function() {
return this.get("type") === "error";
}.property("type")
});
If a controller wants to create a flash message then it ‘needs’ the Flash controller. Here the Application controller creates a flash message in response to an action.
App.ApplicationController = Ember.Controller.extend({
needs: ['flash'],
actions: {
createFlashNotice: function() {
this.get('controllers.flash').createFlash({
type: "notice",
message: "I'm a flash notice."
});
},
createFlashError: function() {
this.get('controllers.flash').createFlash({
type: "error",
message: "I'm a flash error."
});
},
createFlashSuccess: function() {
this.get('controllers.flash').createFlash({
type: "success",
message: "I'm a flash success."
});
}
}
});
We need a view for a flash messages which can remove it in response to a user action.
App.FlashView = Ember.View.extend({
templateName: 'flash',
classNames: ['hide'],
didInsertElement: function() {
this.$().fadeIn(1000);
},
actions: {
click: function(alert) {
this.get('controller').get(
'controllers.flash').removeObject(
this.get('content'));
this.destroy();
}
}
});
JS Bin example. Click on one of the buttons to create a flash message and remove it by clicking on the ‘x’.
Thanks to Eric Berry for the ‘flash’ of inspiration.