How to move a view around the DOM using angular.js?

How to move an element to different places in the DOM using angular js?

I have a list of such items

<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 do is move #overlay from place to place inside the list, without having a hidden duplicate in each element that I specify is hidden / unclosed.

If it 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?

+4
source share
2 answers

Thanks to your clarifications, I can understand that you have a list of items. You would like to be able to select one element in this list (swipe, but possibly other events), and then display an additional DOM element (div) for the selected element. If another element is selected, it should not be selected - thus, only one element should have an additional div.

If the above understanding is correct, you can solve this with simple ng-repeat and ng-show directives, such as:

 <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 will be (only its fragment is shown):

 $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 full jsFiddle: http://jsfiddle.net/pkozlowski_opensource/65Cxv/7/

If you are concerned about having too many DOM elements, you can achieve the same by using the 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 jsFiddle: http://jsfiddle.net/pkozlowski_opensource/bBtH3/2/

+11
source

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 unsuccessful attempts):

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

To store an item that currently has an overlay, a service is required, if any. (I decided not to use a controller for this, since I think that the "service + directive" will make a more reusable component than the "directive + controller".)

 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 can also modify the DOM associated with the element that currently has an overlay.

I tried setting up $ watchs scope and possessing singleton storage and changing scope objects, but I couldn't get $ watch to run when I changed the scope inside the moveOrToggleOverlay function.

+4
source

Source: https://habr.com/ru/post/1434256/


All Articles