This question is come up with Component Example from the homepage of Ember.js, here's the code:
App.GravatarImageComponent = Ember.Component.extend({
size: 200,
email: '',
gravatarUrl: function() {
var email = this.get('email'),
size = this.get('size');
return 'http://www.gravatar.com/avatar/' + hex_md5(email) + '?s=' + size;
}.property('email', 'size')
});
When I try this example I noticed that everytime I input a character the browser will fire a request to get the avatar. If my email address have 30 characters, there will be 30 times requests got fired until the right one was returned from the server. I think this is too inefficient, isn't it?
After digging out the guides, I didn't find there is a way to solve this problem, so I was wondering: is this possible to delay re-compute a computed property for, say, like 1000ms? or is there a better way to deal with this type of scenario?
You can debounce it, which gives you a similar feeling of it reacting without having to do anything other than typing:
App.GravatarImageComponent = Ember.Component.extend({
size: 200,
email: '',
fetchEmail:'',
watchEmail: function(){
Em.run.debounce(this, this.setEmail, 400)
}.observes('email'),
setEmail: function(){
this.set('fetchEmail', this.get('email'));
},
gravatarUrl: function() {
var email = this.get('fetchEmail'),
size = this.get('size');
return 'http://www.gravatar.com/avatar/' + md5(email) + '?s=' + size;
}.property('fetchEmail', 'size')
});
Example: http://emberjs.jsbin.com/lacefi/1/edit
I had to put a debouncer on my observer to limit execution of my actual business logic in one of my project.
In this case, you can change your computed property gravatarUrl
to normal property and move logic to build url on a observer, which observes email
and size
and update gravatarUrl
, and then simply put a debouncer on your observer. I haven’t tested below code but here is the idea:
App.GravatarImageComponent = Ember.Component.extend({
size: 200,
email: '',
gravatarUrl: '',
gravObserver: function() {
Ember.run.debounce(this, this.updateGravUrl, 1000);
}.observes('email', 'size'),
updateGravUrl: function(){
var email = this.get('email'),
size = this.get('size');
this.set('gravatarUrl','http://www.gravatar.com/avatar/' + hex_md5(email) + '?s=' + size);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With