#19: 🔘 Adicionando um checkbox

Agora nós somos capazes de interagir com nossa lista removendo itens. Mas, e se quisermos completar itens e ainda poder vê-los em nossa lista, por exemplo, com uma linha no título do item? Aí entra o checkbox!

Nós iremos ver como:

  • Adicionar uma checkbox

  • Adicionar uma funcionalidade que, quando você clica na checkbox, adiciona uma classe CSS - que adiciona um estilo riscado, a ser adicionada aos nossos itens da lista

  • Editar a lista para responder ao checkbox

  • Adicionar uma nova classe CSS

Agora vamos avançar e adicionar um checkbox em nosso arquivo todo-item.component.ts. Coloque o código abaixo antes da tag {{ item.title }}:

  <input type="checkbox"/>

Agora, para que o checkbox faça alguma coisa, precisamos adicionar um evento de clique que chamaremos de completeItem. Nós também adicionaremos uma classe css, colocar o elemento envolto e a interpolação juntos para estilo. Vamos fazer isso agora:

  <div>
    <input type="checkbox"
          class="todo-checkbox"
          (click)="completeItem()"/>
    {{ item.title }}
  </div>

Quando clicamos no checkbox, o programa irá rodar a função completeItem. Vamos falar sobre o que essa função precisa realizar. Nós precisamos adicionar estilos com CSS no título do item, então, quando o checkbox estiver clicado, teremos uma linha riscando ele. Nós também queremos salvar o status do item no local storage. Para alcançar isso, nós iremos emitir um evento de updae com o novo status do item e obter isso no componente pai.

export class TodoItemComponent implements OnInit {
  @Input() item: TodoItem;
  @Output() remove: EventEmitter<TodoItem> = new EventEmitter();
  @Output() update: EventEmitter<any> = new EventEmitter();

  // put this method below ngOnInit
  completeItem() {
    this.update.emit({
      item: this.item,
      changes: {completed: !this.item.completed}
    });
  }

Mas espere! Como esse código irá afetar a lista quando estamos apenas tocando o checkbox? Bom, o Angular tem essa maravilhosa diretriz chamada NgClass. Essa diretriz aplica ou remove uma classe CSS baseada num valor booleano (verdadeiro ou falso). Existem diversas maneiras de utilizar essa diretiva (veja a documentação da diretiva NgClass), mas nós iremos focar na utilização abaixo:

<some-element [ngClass]="{'first': true, 'second': true, 'third': false}">...</some-element>

No exemplo acima, a classe 'first' e a 'second' vão ser aplicadas no elemento porque têm valor verdadeiro. Já a 'third' não irá ser aplicada, pois seu valor é falso. É aqui que nosso código anterior começa a fazer sentido. Nossa função completeItem irá mudar entre valores verdadeiros e falsos, ditando quando uma classe será aplicada ou removida.

Vamos adicionar o título do item em um <span>, então usar NgClass para aplicar o estilo. Dependendo do item atual completado, nós iremos mostrar uma linha de decoração ou não:

<p class="todo-title" [ngClass]="{'todo-complete': item.completed}">
  {{ item.title }}
</p>

E, finalmente, adicione o CSS em nosso arquivo todo-item.component.css:

  .todo-complete {
    text-decoration: line-through;
  }

Próximo passo é falar para o gerenciador de listas do componente pai o que fazer quando o evento de update for emitido. Para fazer isso, nós temos que ligar a ação de update e o método de update que irá acionar a função apropriada no TodoListService. Então aplicamos aqui:

<app-todo-item [item]="todoItem"
               (remove)="removeItem($event)"></app-todo-item>
</div>

Próximas modificações:

<app-todo-item [item]="todoItem"
             (remove)="removeItem($event)"
             (update)="updateItem($event.item, $event.changes)"></app-todo-item>
</div>

E crie um método adicional para gerenciar o evento de update de item. Muito similar com a função removeItem:

updateItem(item, changes) {
  this.todoListService.updateItem(item, changes);
}

Voila! Quando você clica no checkbox, o css deve adicionar uma linha no título da lista, e se clicar novamente, o checkbox irá remover a linha.

Last updated