Angular2 - добавить класс к элементу на клике

У меня есть список элементов списка и хотелось бы выделить каждый из них после его нажатия. Это легко для меня сделать в jQuery или даже JavaScript, но я теряюсь, когда дело доходит до Angular2.

<ul>
   <li [attr.data-selected]="false" (click)="highlightItem($event)" [class.highlight]="isHighlighted($event)" *ngFor="#item of items"> {{item}} </li>
</ul>

Мой компонент

export class HelloWorld {
    items = ["pineapples", "apples", "tomatoes", "bread"];

    highlightItem(event) {
        event.target.setAttribute("data-selected", "true");
   }

   isHighlighted(event) {
       return event.target.getAttribute("data-selected") == "true";
    }
}

Не знаю, где моя ошибка, или если я использую неправильный метод

Ответ 1

Вам нужно сделать массив в вашем классе, чтобы сохранить статус выделения элемента:

hightlightStatus: Array<boolean> = [];

Объявить локальную переменную в шаблоне, связанном с ngFor:

<ul>
   <li [attr.data-selected]="false" 
       (click)="hightlightStatus[i]=!hightlightStatus[i]" 
       [class.highlight]="hightlightStatus[i]" 
       *ngFor="let item of items, let i = index"> 
       {{item}} 
   </li>
</ul>

Ответ 2

Если я правильно понимаю вопрос, я полагаю, что вы также можете использовать рендер от angular2, чтобы получить код, подобный вашему примеру кода. Для своего собственного проекта я сделал следующее:

В моем шаблоне у меня есть:

<li role="presentation" (click)="userTypeSelect($event)" ><a href="#">Local</a></li>

В моем компоненте у меня есть:

import {Renderer} from '@angular/core';
//other imports

export class SignupComponent implements OnInit {

      constructor(private render:Renderer) { }

      userTypeSelect(event:any){
        event.preventDefault()
        this.render.setElementClass(event.target,"active",false);
      }

}

Стоит отметить, что я не использую это для списка элементов, однако считаю, что он все еще должен работать.

Ссылка на рендер: Рендерер Api Docs

Ответ 3

Есть много способов добиться этого, и все очень просто.

Примеры:

<li *ngFor="let n of list" (click)="select(n)" [ngClass]="{active: isActive(n)}">
  <a>{{n}}</a>
 </li>

 select(item) {
      this.selected = item; 
  };
  isActive(item) {
      return this.selected === item;
  };

Только с использованием HTML

<li *ngFor="let n of list" [class.active]="clicked === n" 
         (click)="clicked = n">
       <a>{{n}}</a>
    </li>

Добавить класс по клику и удалить, если мы нажмем на тот же

select(item) {
   this.selected = (this.selected === item ? null : item); 
};

Только с использованием HTML

<li *ngFor="let n of list" [class.active]="clicked === n" 
       (click)="clicked = (clicked === n ? null :n)">
     <a>{{n}}</a>
   </li>

Подробнее

Ответ 4

По названию вашего вопроса вы хотите добавить новый класс в li при его нажатии, верно?

Если это так, то это может быть просто так:

 <ul>
   <li (click)="highlightItem($event)" *ngFor="let item of items">
     {{item}}
   </li>
 </ul>

export class HelloComponent {
  public items: string = ['Apple', 'Banana', 'Pear', 'Grapes', 'Watermelon'];

  public highlightItem(event) {
    if (! event.target.classList.contains('highlighted')) {
      event.target.classList.add('highlighted');
    }
  }
}

Ответ 5

Это может помочь вам

export class ContactComponent implements OnInit {

  values:Object[];


  ngOnInit() {
    this.values=[{name:'Alex',done:false},{name:'Jon',done:false}];
  }

  completed(i:number){
    if(this.values[i])
      this.values[i]['done']=!this.values[i]['done'];
  }

}

HTML:

<ul>
    <li *ngFor="let v of values;let i='index'" 
        (click)='completed(i)'
        [class.checked]="v.done" 
        >       
        {{v.name}}<span class="close">×</span>
    </li>
</ul>