24

So, the question is fairly simple...

I have a table and some angular logic on it (calculating styles, etc)... specifically I have this on THs

[class.hidden] = "column.group !== 'key-data' && currentTableView !== column.group"

For my table sticky headers functionality I need to clone the table and position it fixed.. using a directive, that does something like this (simplified)

let newTable = element.cloneNode(true);
body.appendChild(newTable);

obviously the angular logic is not applied to the newTable, but I want it to be...

How do I do it?

3
  • Why don't you just create a new instance with the same data? I don't think there is a way to clone it this way. Commented Aug 25, 2016 at 8:15
  • New instance + storing/getting properties (via service or in worst case from localStorage,..) Commented Aug 25, 2016 at 8:20
  • is not for getting data.... is for switching visible and hidden columns. There is some angular logic for ngClass put on THs... I want to retain the same logic on cloned THs Commented Aug 25, 2016 at 8:52

1 Answer 1

13
+100

So I did some research and this is what I came up with.

You can do it and it isn't actually that hard using templates and the [ngTemplateOutlet]. This is how it works:

@Component({
  selector: 'my-app',
  template: `
    <ng-template #temp>
        <h1 [ngStyle]="{background: 'green'}">Test</h1>
        <p *ngIf="bla">Im not visible</p>   
    </ng-template>
    <ng-container *ngTemplateOutlet="temp"></ng-container>
    <ng-container *ngTemplateOutlet="temp"></ng-container>
    `
})

export class AppComponent {
    bla: boolean = false;
    @ContentChild('temp') testEl: any;
} 

So you create a reference template, add all of your logic inside of it, and then you just create as many copies of the template using the [ngTemplateOutlet]. All of the inner bindings and angular functionality is retained.

Here is a working plunker:

http://plnkr.co/edit/jPt5eKUfLUe9FxnLH8bL?p=preview

As you can see I've tested it with *ngIf and [ngStyle] and they work as expected and I don't see any reason why any other kind of directive wouldn't work.

You can even use *ngFor but then you need to provide the [ngOutletContext]. I've done that in a library I'm working on you can see an example here:

https://github.com/flauc/ng2-simple-components/blob/master/src/select/select.component.ts

Sign up to request clarification or add additional context in comments.

4 Comments

Looks good... would like to award you the bounty but haven't checked/tested it yet if that's what I am looking for... it looks like it is close
I've used it successfully a few times now and i hope it works for you as well.
ERROR TypeError: templateRef.createEmbeddedView is not a function, <ng-template should be used instead of <template>
Thanks @VictorBredihin the implementation changed from when this was written. I've updated my answer so it's aligned with the current version of angular.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.