Force route to rerender template each time it's hit


#1

I’ve got an app which lists employees on the left, and their details page on the right. When clicking the employee on the left, it loads the person route. The template for the person route displays the person’s image which is pulled from our website.

The problem is that some people do not have photos yet. So I’m using an onerror attribute on the image to run a “replace with anonymous image” method:

<img {{bind-attr src=model.imagePath}} onerror="utils.imageReplace(this);" />

and the method

imageReplace = function(img) {
    /*
        Replaces missing avatar images with a generic image
    */
    img.onerror = '';
    img.src = "images/anonymous.png";
};

The anonymous photo loads the first time it is displayed, but when you go to another person, then BACK to a person with a missing photo the image is broken (see above). I’m pretty sure because Ember is caching the template and simply replacing the content as expected. The problem is that it does not then rerun the onerror method for the image.

I’m trying to determine the best way to force Ember to rerender the template each time the route is loaded, and not pull it from cache.


#2

Not sure if it’s a good idea to manually set a bound attribute.

I’d create a component for this particular case:

// app/components/avatar-image.js

export default Ember.Component.extend({
  tagName: 'img',
  attributeBindings: ['src'],
  fallbackSrc: 'http://placehold.it/100x100',
  
  setupEventHandlers: function() {
    this.$().on('error', function(e){
      return this.loadError(e);
    }.bind(this));
  }.on('didInsertElement'),
  
  willDestroyElement: function(){
    this.$().off('error');
  },
  
  loadError: function() {
    this.set('src', this.get('fallbackSrc'));
  }
});

#3

@xeppelin That’s a nice approach. I’ve never worked with Components before. So that content goes in a JS file, then it would just be used like this?

{{avatar-image src=model.imagePath}}

#4

Ah, sorry. If you use Ember App Kit, then yes. Otherwise:

App.AvatarImageComponent = Ember.Component.extend({
  // ...
});

The usage is exactly as you mentioned before:

{{avatar-image src=model.imagePath}}

#5

Ah, I’m not using EAK currently.

And BAM, that works beautifully. This is my first use of Components and it’s a pretty slick implementation. Thank you!