简体   繁体   中英

Angular 8 toggle CSS class using ngFor on click

I have found similar scenarios to this one, but I haven't yet found this exact scenario. Sorry if I missed it.

In Angular 8, I am using an *ngFor to iterate through some message objects. This displays the message title and date/time in a row of vertical boxes to the left of the screen. What I'm trying to get to is when one box is clicked, it becomes active and changes color. I have this working, but the problem is that the "active" class does not inactivate when another box is clicked. This is the problem I'm trying to solve.

Here is my current code with CSS:

<div *ngFor="let msg of messages; let i = index">
  <a class="list-group-item list-group-item-action" 
      data-toggle="list" href="#home" role="tab" 
      [ngClass]="{ 'active' : isActive}" (click)="popIt(i)">
    <span id="msgSubject1">{{msg.Subject}}</span>
    <br />
    <span class="datetimeCls" id="datetime1">
      {{msg.DateCreated | date : 'short' }}
    </span>
  </a>
</div>
popIt(num: string) {
  var number = num;
  this.SubjectDisplay = this.messages[num].Subject;
  this.DateDisplay = this.messages[num].DateCreated;
  this.TextDisplay = this.messages[num].Body;
}
.list-group .list-group-item {
  color: grey;
  font-weight: bold;
  font-family:"Gill Sans" Verdana;
  font-size: 15px;
  background-color: #FFFFFF;
}

.list-group .list-group-item.active {
  background-color: lightgray !important;
  border-top: solid 2px grey;
  border-bottom: solid 2px grey;
  color: grey;
}

This displays the object properties as expected, the clicks work, but it makes every box active as they're clicked. They do not inactivate.

Any direction, suggestions or examples would be appreciated! Thank you!

One way to do it is to have an activeMessage property:

public activeMessage: Message; // Use the appropriate type here

which is set on click and tested in the class binding:

<div *ngFor="let msg of messages">
  <a [class.active]="msg === activeMessage"
    (click)="activeMessage = msg; doOtherStuff()" ... >
    ...
  </a>
</div>

See this stackblitz for a demo.

Change your code and store information in your parent component about some unique identifier of message which was clicked. And then you can easily add click listener to component and inside of parent component update stored id. But you have to change a little you HTML [ngClass] directive, to return true if message.Id===clickedMessageId . Or you can store whole message in fe clickedMessage , then you can do message===clickedMessage . Another way you can achieve it, you can create custom directive and service , when you click directive notify service to unclick every other object. But you have to remember to remove them from service, once directive has been destroyed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM