Search code examples
jqueryangularjsappendtotransclusion

Inject a unique DOM element in at a specific position in a ng-repeat using Angular


I have a complex grid like directive that is bound to a long list model object. For one of my apps, I have a list in which I need to inject the directive in the row that is selected. The code is something like

<div id='grid-like' myComplexDirective style='display:none'></div>

<div ng-repeat='item in items'>
    <div class="data-row">
        <!-- stuff with item object -->
        <button ng-click='insertControl()'></button>
    </div>
    <!-- Here is where i'd like to inject the grid-like control and show/hide when button is clicked -->
</div>

I need to do so to avoid having several instances of the complex component (right now, it's included in each row an shown/hidden depending on a toggle value of the scope) because it's heavy and make the app sluggish. I've tried to move the element in jquery using appendTo method in the insertControl method. Unfortunately, it doesn't work as soon as I change the view. After some research, I've found out that I need to use Angular directives with transclusion or using $compile.

What is the angular way to do the jquery appendTo that would work across views?


Solution

  • Use ngIf.

    From Angular documentation:

    The ngIf directive removes or recreates a portion of the DOM tree based on an {expression}. If the expression assigned to ngIf evaluates to a false value then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM.

    <div ng-repeat='item in items'>
        <div class="data-row">
            <!-- stuff with item object -->
            <button ng-click='item.insertControl=true'></button>
        </div>
        <!-- Here is where i'd like to inject the grid-like control and show/hide when button is clicked -->
        <div ng-if="item.insertControl">
             ... some complex control ...
        </div>
    </div>
    

    If you're worried about performance use ngShow instead. DOM manipulation is expensive, ngShow avoids this.