8

Is there a way to clone an element in AngularJS, with its bindings intact?

I am trying to create an image pre-loader for a gallery. The image loads off screen and is then moved into one of three columns depending on its size. So it actually does need to be moved with JavaScript since I don't know until it is loaded which container it is supposed to go into.

So assume I have something like:

<img ng-src="/some/{{image}}" ng-click="doStuff()" />

I want the clone to be identical to this, with the ng-click binding intact. The problem I am encountering is that if I clone the element using element.clone().appendTo(someOtherElement) then the ng-click binding is lost along the way. When the element is inserted in the DOM Angular does not realize that it needs to create new bindings.

I have been experimenting with $compile, but I can't figure out how to clone an existing element using it without manually copying all attributes.

The cloning is done by a directive and I am only using Angular (no jQuery save what is included in Angular).

Erik Honn
  • 7,576
  • 5
  • 33
  • 42
  • 3
    with angular think of reorganizing data, not moving elements in DOM as you would with jQuery. angular will then take care of the DOM for you. Create a demo showing what you are trying to do. To organize your images should be fairly easy setting a property on each object within your loader, and column filtering according to that property – charlietfl Nov 11 '13 at 11:22
  • 1
    I've thought of that. The reason I was looking to actually clone in this case is that I need to pre-load the images before I can figure out where they belong. But perhaps you are right, I should try updating the model with a new "place in X"-property on load and filtering the containers on that. – Erik Honn Nov 11 '13 at 11:58
  • yes to second part...update model...let angular handle it from there. The image loader is asynch, but, so is AJAX. angular was built with tons of ajax in mind – charlietfl Nov 11 '13 at 12:01
  • Read this [how-do-i-think-in-angularjs-if-i-have-a-jquery-background](http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background) – charlietfl Nov 11 '13 at 12:03
  • 1
    There as several reasons why I need to actually pre-load the image in the DOM (getting sizes that are not in meta data, preventing visible loading) so cloning in this case makes sense. But not worth it considering the bindings :P – Erik Honn Nov 11 '13 at 12:14

1 Answers1

1

You should do three separate ng-repeats:

<div ng-controller="myController">
     <div class="col1">
          <img ng-src="/some/{{image.src}}" ng-click="doStuff()" ng-repeat="image in imagesForColOne" />
     </div>

     <div class="col2">
          <img ng-src="/some/{{image.src}}" ng-click="doStuff()" ng-repeat="image in imagesForColTwo" />
     </div>

     <div class="col3">
          <img ng-src="/some/{{image.src}}" ng-click="doStuff()" ng-repeat="image in imagesForColThree" />
     </div>

</div>

In your controller you should load your images asynchronously and then push them into one of the three arrays depending on its size.

Jeremythuff
  • 1,518
  • 2
  • 13
  • 35