Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delay computed properties to recomputed themselves in Ember.js?

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?

like image 696
nightire Avatar asked Jan 10 '23 03:01

nightire


2 Answers

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

like image 122
Kingpin2k Avatar answered Jan 17 '23 19:01

Kingpin2k


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);
  }
});
like image 23
lame_coder Avatar answered Jan 17 '23 19:01

lame_coder