Home > Net >  How can I change the value of an Angular template variable?
How can I change the value of an Angular template variable?

Time:06-08

I want to change the value of a template variable based on a condition.

<ng-container *ngIf="'first' as myVar">
  <ng-container *ngIf="myVar == 'first'">
    <ng-container *ngIf="'later' as myVar">
      <div>{{myVar}}</div>
    </ng-container>
  </ng-container>

  <div>{{myVar}}</div>
</ng-container>

However I am getting

later
first

instead of

later
later

(probably the second variable is different than the first one and exists only in the scope of the second variable (which seems to be a weird way to implement template variables)).

Is there a simple way to change the value of a template variable?

I would also like to know if there is a way to join the condition ("myVar == 'first'") and the assignment ("'later' as myVar") into one expression instead of two nested <ng-container>.

CodePudding user response:

Angular allows you to set a ternary expression inside the structural directives such as *ngIf="argument === value ? true : false " Here is a stackblitz to show you this in action. (Change the value of name from Angular to React in the link to see how *ngIf="" will behave)

Thus you do not need to nest *ngIf="" the way is done in your code above.You can also do the ternary expressions in the 'controller' - Typescript file and that's cleaner and more readable.

Such as:

public isAngular: boolean = this.name === 'Angular' ? true : false

And then you bind isAngular to your template *ngIf="".

You can also use *ngIf="condition; else fallback" where fallback is a template reference to another content <ng-template #fallback>content goes here</ng-template>

CodePudding user response:

 <ng-container *ngIf="myVar === 'first'" else #later>
   <div>{{myVar}}</div>
   <div>{{myVar}}</div>
 </ng-container>

 <ng-template #later *ngIf="myVar === 'later'" >
   <div>{{myVar}}</div>
   <div>{{myVar}}</div>
 </ng-template>

CodePudding user response:

Template Variables

For your main question, your elements can only see the the template variables of their parents.

For example, this will fail to compile:

<ng-container *ngIf="'later' as myVar">
  <div>{{myVar}}</div>
</ng-container>
<div>{{myVar}}</div> <!-- No parent TV or reference in component.ts -->

So your conclusion is right, in that it is a different value, although it isn't all that weird if you think of it as living on that DOM-Element. They are more so meant as references to that particular element, and are indeed less useful for logic. For that you're better off binding to your component.ts file.

In short, I don't think reassigning of Template Variables is possible. You will just get the value of the closest parent.

Second Question

For your second question, this is a little shorter (but /w same result):

<ng-container *ngIf="'first' as myVar">
  <ng-container *ngIf="(myVar == 'first' ? 'later' : '') as myVar">
    <div>{{myVar}}</div>
  </ng-container>
  <div>{{myVar}}</div>
</ng-container>

You could also (ab)use ngTemplateOutlet to achieve something similar:

<ng-template #s [ngTemplateOutlet]="s" let-a [ngTemplateOutletContext]="{ $implicit: 'first' }">
    {{a}}
    <ng-template #t [ngTemplateOutlet]="t" let-b [ngTemplateOutletContext]="{ $implicit: a == 'first' ? 'later' : '' }">
    {{b}}
    </ng-template>
</ng-template>

Here's a Stackblitz for you.

Presentation Logic in Component.ts

It is actually perfectly fine to have logic for presentation in your component. In fact it is pretty much the only thing that should be in your presentation components.

It is a best practice to use the approach of Container & Presentation Components.

Container component

  • Manages the state by interacting with service/store
  • Contains only minor presentation, like for example a header/title
  • Passes state to presentation components using input properties

Presentation component

  • Presents/renders the data, but does not directly interact with state
  • Communicates with container component using output properties
  • Related