1

I have a little problem with angularJS when it comes to finding elements. It seems that my objects are changed when i use element.find('type').attr('id' ,someid);

Here some further information:

  • I use the directive only in one position
  • I use angularjs 1.3.10.

i prepared a plunker http://plnkr.co/edit/fW4HsbqRhMWiw8hSLTVH?p=preview which shows what i mean. It alerts the previous found element after it has found another. What happens is that the previously found element is the same as the now found element ( a little bit tricky to explain, see the comments in the code to see what exactly i mean).

My link function looks so:

function link(scope,element,attrs)
{
    var _gradientCanvas = element.find('canvas').attr('id' , 'chColorGradient');
    if(_gradientCanvas[0].id === 'chColorGradient')
    {
        var _gradientContext = _gradientCanvas[0].getContext('2d');
    }
    var _overlayCanvas = element.find('canvas').attr('id' , 'chColorGradientOverlay');
    if(_overlayCanvas[0].id === 'chColorGradientOverlay')
    {
        var _overlayContext = _overlayCanvas[0].getContext('2d');
        alert(_gradientCanvas[0].id); //alerts: chColorGradientOverlay , but it should alert chColorGradient

    }
    var _arcOverlay = element.find('canvas').attr('id' , 'chColorArcOverlay'); 
    if(_arcOverlay[0].id === 'chColorArcOverlay')
    {
        var _arcContext = _arcOverlay[0].getContext('2d');
        alert(_gradientCanvas[0].id);//alerts: chColorArcOverlay , but it should alert chColorGradient
        alert(_overlayCanvas[0].id);//alerts: chColorArcOverlay , but it should alert chColorGradientOverlay
    }
}

Here is the template

<canvas class="chColorPickerCanvas" id="chColorGradient" width="255px" height="255px">
</canvas>
<canvas class="chColorPickerCanvas" id="chColorGradientOverlay" width="255px" height="255px">
</canvas>
<canvas class="chColorPickerCanvas" id="chColorArcOverlay" width="255px" height="255px">
</canvas>

i am not quite sure why it does this. i tried to debug into it with netbeans but it seems really that it changes my var _gradientCanvas etc after i called element.find another time. Is there a reason for this ?

Bongo
  • 2,933
  • 5
  • 36
  • 67
  • 1
    your code finds _first_ `canvas` inside an element: `element.find('canvas')` and then `attr('id' , 'chColorGradient')` changes its `id` to `chColorGradient`: `element.find('canvas').attr('id' , 'chColorGradient');`. Second time your code again finds _first_ canvas and changes its id to `chColorGradientOverlay`: `var _overlayCanvas = element.find('canvas').attr('id' , 'chColorGradientOverlay');` and so on – Dmitry Pavliv Feb 21 '15 at 18:08
  • 1
    oh, i thought it was used to filter. I now have to find a different approach. Thanks for the quick answer – Bongo Feb 21 '15 at 18:15

1 Answers1

2

Here is what actually happens:

  • element.find('canvas') returns all cavases inside element.
  • element.find('canvas').attr('id' ,someid) changes id attribute of first returned canvas.
  • so, _gradientCanvas[0], _overlayCanvas[0] and _arcOverlay[0] all refers to the same element - first canvas inside element. And this explains described behaviour - attr('id' , 'chColorGradient') doesn't filters by id, but changes id of first element in collection.

If you want to filter by id, look into this post: AngularJS: How to .find using jqLite?

Community
  • 1
  • 1
Dmitry Pavliv
  • 35,333
  • 13
  • 79
  • 80
  • since i know the order of elements in the template would it be considered save to use var canvasses = element.find('canvas'); var c1 = canvasses[0]; var c2 = canvasses[1] to get the element i am wanting ? – Bongo Feb 21 '15 at 18:28
  • yes, if you can confirm that order woudn't change, you can rely on it, here is the [plunker](http://plnkr.co/edit/3C9Pjn?p=preview) – Dmitry Pavliv Feb 21 '15 at 18:36
  • 1
    okay thanks i will keep that in mind when changing my code. Since your answer explains where i was wrong, another helpfull thread is contained and seems to help me along i will mark his as accepted answer. – Bongo Feb 21 '15 at 18:40