How do I move a view around the DOM with angular.js?

How can I move an element to different places in the DOM with angular js?

I have a list of elements like so

<ul id="list" ng-controller="ListController">
    <li ng-controller="ItemController"><div>content</div></li>
    <li ng-controller="ItemController"><div>content</div></li>
    <li ng-controller="ItemController"><div>content</div></li>
    <li ng-controller="ItemController">
        <div>content</div>
        <div id="overlay"></div>
    </li>
</ul>

What I'm trying to accomplish is moving the #overlay from place to place within the list without having to have a hidden duplicate in every item that I flag hidden/unhidden.

If this was jquery I could just do something like this:

$("#overlay").appendTo("#list li:first-child");

Is there an equivalent way to do this in angular?

Thanks to your clarifications I can understand that you've got a list of items. You would like to be able to select one item in this list (swipe but potentially other events as well) and then display an additional DOM element (div) for a selected item. If the other item was selected it should be un-selected - this way only one item should have an additional div displayed.

If the above understanding is correct, then you could solve this with the simple ng-repeat and ng-show directives like this:

<ul ng-controller="ListController">
    <li ng-repeat="item in items">
        <div ng-click="open(item)">{{item.content}}</div>
        <div ng-show="isOpen(item)">overlay: tweet, share, pin</div>
    </li>
</ul>

where the code in the controller would be (showing a fragment of it only):

$scope.open = function(item){
    if ($scope.isOpen(item)){
        $scope.opened = undefined;
    } else {
        $scope.opened = item;
    }        
};

$scope.isOpen = function(item){
    return $scope.opened === item;
};

Here is the complete jsFiddle: http://jsfiddle.net/pkozlowski_opensource/65Cxv/7/

If you are concerned about having too many DOM elements you could achieve the same using ng-switch directive:

<ul ng-controller="ListController">
    <li ng-repeat="item in items">
        <div ng-click="open(item)">{{item.content}}</div>
        <ng-switch on="isOpen(item)">
            <div ng-switch-when="true">overlay: tweet, share, pin</div>
        </ng-switch>        
    </li>
</ul>

Here is the jsFiddle: http://jsfiddle.net/pkozlowski_opensource/bBtH3/2/

As an exercise for the reader (me), I wanted to try a custom directive to accomplish this. Here is what I came up with (after many failed attempts):

<ul ng-controller="ListController">
    <li ng-repeat="item in items">
        <div singleton-overlay>{{item.content}}</div>
    </li>
</ul>

A service is required to store the element that currently has the overlay, if any. (I decided against using the controller for this, since I think a 'service + directive' would make for a more reusable component than a 'controller + directive'.)

service('singletonOverlayService', function() {
    this.overlayElement = undefined;
})

And the directive:

directive('singletonOverlay', function(singletonOverlayService) {
    return {
        link: function(scope, element, attrs) {
            element.bind('click', moveOrToggleOverlay);

            function moveOrToggleOverlay() {
                if (singletonOverlayService.overlayElement === element) {
                    angular.element(element.children()).remove();
                    singletonOverlayService.overlayElement = undefined;
                } else {
                    if (singletonOverlayService.overlayElement != undefined) {
                        // this is a bit odd... modifying DOM elsewhere
                        angular.element(singletonOverlayService.overlayElement.children()).remove();
                    }
                    element.append('<div>overlay: tweet, share, pin</div>')
                    singletonOverlayService.overlayElement = element;

jsFiddle: http://jsfiddle.net/mrajcok/ya4De/

I think the implementation is a bit unconventional, though... the directive not only modifies the DOM associated with its own element, but it may also modify the DOM associated with the element that currently has the overlay.

I tried setting up $watches on scope and having the singleton store and modify scope objects, but I couldn't get the $watches to fire when I changed the scope from inside the moveOrToggleOverlay function.