0
votes

I am trying to create my first ember component, a wrapper for ChordsJS to display guitar chords.

My component template looks like this:

<chord {{bind-attr name=name positions=positions fingers=fingers size=size }}></chord>

And my component JS is here:

import Ember from 'ember';

export default Ember.Component.extend({
  name: 'D',
  positions: 'xx0232',
  fingers: '---132',
  size: '3',
  didInsertElement: function() {
    chords.replace();
  }
});

This renders correctly, but since didInsertElement is in the component.js code, it fires once for each element on the page, so if my markup is

<chord></chord>
<chord></chord>

There will be 4 rendered elements instead of two. Is there another way to include the didInsertElement call so that it only fires once per template?

Edit: another approach would be for me to hack the ChordJS library and make chords.replace() work for a single element: chords.replace(element). To do this, I would need a way to access the dom element in the component.js ?

1

1 Answers

1
votes

I hacked around this by modifying the ChordJS library to include this function to render just one element instead of all of the <chord></chord> elements.

var ReplaceOneElement = function(elem) {
        var name = $(elem).find('chord').attr('name')
        var positions = $(elem).find('chord').attr('positions')
        var fingers = $(elem).find('chord').attr('fingers')
        var size = $(elem).find('chord').attr('size')
        var chord = ChordBoxImage(name, positions, fingers, size);
        var canvas = $('<canvas></canvas>').attr({width:chord.getWidth(), height:chord.getHeight()}).insertAfter(elem);
        var ctx = canvas[0].getContext('2d');
        chord.Draw(ctx);
}

and calling it in my component once per element:

didInsertElement: function() {
    chords.replaceOne(this.get('element'));
}

I would still like to know if there is a more Emberesque way of approaching this.