2

I am working on an EmberJS application (my first one) and I am hitting a few stumbling blocks.

I am making pretty good progress with most of the application logic, however one thing that is really nagging at me is IconicJS not working properly. Essentially, IconicJS "injects" the SVG data into an <img> element, and as such needs to be run every time there are new <img> elements with the appropriate class. One would do so with something like:

IconicJS().inject("img.iconic");

So I gave it a shot by putting it in app/views/application.js alongside Foundation's initialization:

import Ember from 'ember';

export default Ember.View.extend({
  didInsertElement: function() {
    this.$().foundation();
    IconicJS().inject('img.iconic');
  }
});

This appears to only trigger on initial page loads, however. As a result, any navigation after the initial page load results in svg <img> tags not getting rendered properly.

I am not sure if it has to do with the way I am loading my data, though, as I am very new to Ember.

If anyone has any ideas, I would really like to hear them. I apologize in advance if I am not providing enough information. I'll gladly add more if needed.

EDIT

Thanks to MrVinz, I was able to finish this up. What I needed was an initializer. Since I am using an Ember-CLI app, that would reside in app/initializers/initialize-assets.js. The content of that file is (in my case):

import Ember from 'ember';

export default {
  name: 'initialize-assets',
  initialize: function() {
    Ember.Route.reopen({
      renderTemplate: function() {
        this.render();
        var initResources = function() {
          Ember.$().foundation();
          IconicJS().inject('img.iconic');
        };
        Ember.run.scheduleOnce('afterRender', initResources);
      }
    });
  }
};

While I am still not 100% that this is the best way to solve this problem from a performance standpoint, it seems to work for now (all applicable <img> tags are getting injected and Foundation is still working properly) so I think this solves it for now.

Thanks again!

Mylan Connolly
  • 494
  • 1
  • 5
  • 15
  • Just a small comment with the initialize version i would replace the 'this.render()' by a 'this._super()' – MrVinz Jan 16 '15 at 01:09

2 Answers2

1

Well that's work only for your application view ;)

For something more "generic" which work on any route you can try do something like in this post : Global hook in Ember when template is rendered

With cli you can create a CustomRoute in app/routes/custom.js

export default Ember.Route.Extend({
    renderTemplate : function(){
    this.render();var myfunction=function(){
      //do your jquerystuff here
       Ember.$().foundation();
       IconicJS().inject('img.iconic');
    }
    Ember.run.scheduleOnce('afterRender', myfunction);
  }
});

If it's for using on all your routes you can "Reopen" the default framework Route implementation in an initializer like explained in this post : Ember CLI: where to reopen framework classes

Community
  • 1
  • 1
MrVinz
  • 874
  • 6
  • 15
  • Thank you MrVinz, I suspected it had to do with a misunderstanding I have with Ember. I created the `app/routes/custom.js` file that you mentioned, but I am a little unclear on reopening. Do I have to put logic into the reopening? And would I reopen the CustomRoute or Ember.Route? Sorry for the questions, I feel like it's something basic I am missing! Thanks! – Mylan Connolly Jan 15 '15 at 15:50
  • Nevermind, I got it! Updating my question with some other specifics in case anyone else has a similar issue. Thanks again! – Mylan Connolly Jan 15 '15 at 17:51
1

I know this questions has already been answered, but another approach I would recommend is creating a custom icon component that calls IconicJS().inject after the component renders.

export default Ember.Component.extend({
  didRender() {
    Ember.run.scheduleOnce(() => {
      IconisJS.inject('img.iconic');
    };
  }
});

I'm not super familiar with Iconic, so I don't know if there's a way to be more specific and only inject the icon into the current component, but if it supports specifying any selector for the inject method, you could certainly do that.

awgreenarrow08
  • 165
  • 1
  • 8
  • Hey sorry I just saw your comment... I like this idea and it's probably a more ideomatic way to do it these days. I want to say back when I asked it, components weren't all that widely used yet. Good call! – Mylan Connolly Mar 02 '16 at 21:22