We’ve been adding user notifications for asynchronous operation completes into our app lately. Mainly when the user clicks save/send/commit/etc, once we hear back from the server we pop up a little message informing the user it was successful. Here is an example, apparently “new users” can’t post images (seems useful?): http://i.imgur.com/lsY1ksu.png
Thus far, we’ve been using a few different “widgets” that will do the following:
App.ParticipantAddedNotification = Ember.View.extend({
didInsertElement: function() {
this.get('controller').on('participantAdded', this.show);
},
willDestroyElement: function() {
this.get('controller').off('participantAdded', this.show);
},
show: function() {
this.set('visible', true);
Ember.run.later(this, function() {
this.set('visible', false);
}, 5000);
}
});
And of course our controllers then do the follow:
App.ManageParticipantsController = Ember.Controller.extend(Ember.Evented, {
addParticipant: function() {
var self = this;
doAjax().then(function() {
self.trigger('participantAdded');
}
});
My question is, is this the right way to go about it? Any other alternatives?
A slightly different approach could be using a combination of a controller, template and the render helper:
App.NotificationController = Ember.Controller.extend({
message: "",
hasMessage: function() {
return !!this.get('message')
}.property('message'),
messageDidChange: function() {
var self = this;
if(this.get('message')) {
Ember.run.later(function(){self.set('message', null);}, 5000);
}
}.observes('message')
});
App.ManageParticipantsController = Ember.Controller.extend(
needs: ['notifications'],
addParticipant: function() {
var self = this;
doAjax().then(function() {
self.get('controllers.notifications').set('message', 'Participant added');
});
}
});
Then in your notification.handlebars
<div {{bindAttr class="hasMessage">
{{message}}
</div>
and include all this using the render helper in your main application template or wherever makes sense:
{{render 'notification'}}
Hopefully that’s all syntactically correct. You could extend this so that messages is an array and could respond appropriately based on the array changing.
1 Like
Hey – How about that. I didn’t even think of that. Thanks for the suggestion @robmonie!
I’d love to hear what others think about these two (or if they have a third option)
Hey @workmanw —
I’ve done something very similar to @robmonie, but as he indicated as a possibility, I wanted to be able to queue up my notifications (that may not necessarily all be the same). In my case, I included CSS animation on a notification element that lasted for 5 seconds so it would appear and disappear (and if another exists, immediately reappear). The template was bound to {{firstObject}}
.
App.NotificationsController = Ember.ArrayController.extend({
currentMessageDidChange : function() {
if( this.get("firstObject") ) {
Ember.run.later( this, function() {
this.removeAt(0);
}, 5000);
}
}.observes("firstObject")
});
App.ManageParticipantsController = Ember.Controller.extend({
needs : ["notifications"],
addParticipant : function() {
var self = this;
doAjax().then(function( message ) {
self.get("controllers.notifications").pushObject( message );
});
}
});
@Spencer_Price Thanks for sharing!
I slept on it last night and I was able to convince myself that your (and @robmonie’s) approach was more MVC proper than my initial approach. I think I’ll pursue this route.