Tommazo
Tommazo

Reputation: 87

Conditionally swap elements position in a row

I have a component that displays a row in a grid-system simil-bootstrap. It is as simple as an image on the left and some body text on the right, both pulled dynamically from a CMS.

I am trying to add a condition that would display the text first and then the image, or vice versa. ng-container and ng-template seems like the way to go, but I can't figure out how.

I am looking for something like:

<ng-container *ngIf="content.switched; then Image and Text; else Text and Image"></ng-container>

<ng-template #Image> ... </ng-template>
<ng-template #Text> ... </ng-template>

Thanks!

Upvotes: 1

Views: 884

Answers (2)

Martin Parenteau
Martin Parenteau

Reputation: 73731

It can be done with two ng-container elements, each one displaying a template with the ngTemplateOutlet directive and selecting the template with a conditional expression:

<ng-container *ngTemplateOutlet="content.switched ? Image : Text"></ng-container>
<ng-container *ngTemplateOutlet="content.switched ? Text : Image"></ng-container>

<ng-template #Image>...</ng-template>
<ng-template #Text>...</ng-template>

See this stackblitz for a demo.

Upvotes: 2

A.Winnen
A.Winnen

Reputation: 1698

I guess the best way to do this is by using CSS Flexboxes (row vs row-reverse). If you cannot use Flexbox, or just want to to this using Angular, a suitable approach could be using the directive's or component's ViewContainerRef to add the templates in the desired order:

@Component({
    ...
})
public class AnyComponent implements OnInit {
    @ViewChild('Image')
    public imageTemplate: TemplateRef<any;>
    @ViewChild('Text') // grabs a reference to the <ng-template #Text>
    public textTemplate: TemplateRef<any;>

    constructor(private viewContainer: ViewContainerRef) {}

    public ngOnInit(): void {
       if(condition) {
          this.viewContainer.createEmbeddedView(this.textTemplate);
          this.viewContainer.createEmbeddedView(this.imageTemplate);
       } else {
          this.viewContainer.createEmbeddedView(this.imageTemplate);
          this.viewContainer.createEmbeddedView(this.textTemplate);
       }

    }
}

Upvotes: 0

Related Questions