> For the complete documentation index, see [llms.txt](https://koziuk-s.gitbook.io/angular-starter/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://koziuk-s.gitbook.io/angular-starter/strukturni-direktivi.md).

# Структурні директиви

Структурні директиви змінюють структуру DOM за допомогою додавання або видалення HTML-елементів. Структурні директиви позначаються зірочкою `*`

Розглянемо три структурні директиви: ngIf, ngSwitch і ngFor.

### ngIf

Дозволяє видалити або, навпаки, відобразити елемент за певної умови.

{% code title="app.component.html" overflow="wrap" lineNumbers="true" %}

```markup
<p *ngIf="true">Title</p>
```

{% endcode %}

### ngSwitch

Дозволяє вбудувати в шаблон конструкцію switch..case і в залежності від результату її виконання виводить той чи інший блок.

{% code title="app.component.html" overflow="wrap" lineNumbers="true" %}

```markup
<div [ngSwitch]="'Angular'">
  <p *ngSwitchCase="'Angular'">Angular Course</p>
  <p *ngSwitchCase="'TypeScript'">TypeScript Course</p>
  <p *ngSwitchCase="'JavaScript'">JavaScript Course</p>
  <p *ngSwitchDefault>HTML Course</p>
</div>
```

{% endcode %}

### ngFor

Дозволяє перебрати в шаблоні елементи масиву.

{% code title="app.component.html" overflow="wrap" lineNumbers="true" %}

```markup
<p *ngFor="let item of items">{{item}}</p>
```

{% endcode %}

Також при роботі з директивою ngFor можна користатися змінною індекс, яка при першій ітерації  циклу, має значення 0 і збільшується на 1 при кожній наступній.

{% code title="app.component.html" overflow="wrap" lineNumbers="true" %}

```markup
<p *ngFor="let item of items; let i = index">{{i + ' ' + item}}</p>
```

{% endcode %}

{% hint style="info" %}
Це вбудовані структурні директиви. Також ми можемо створювати і власні структурні директиви.
{% endhint %}

## Завдання.

* Створити папку **core**
* В папці **core** створити папку **interfaces**
* В папці **interfaces** створити файл **todo.interfase.ts**

{% code title="todo.interface.ts" overflow="wrap" lineNumbers="true" %}

```typescript
export class Todo {
  id: number;
  title: string;
  description: string;
  isDone: boolean;
}
```

{% endcode %}

* В паку **interfaces** додати барл файл **index.ts** (barrel file)

{% code title="index.ts" overflow="wrap" lineNumbers="true" %}

```typescript
export * from './todo.interface';
```

{% endcode %}

* Створити компонент **todos**

{% code title="cmd" %}

```css
ng g c pages/todos
```

{% endcode %}

* Додати список - **todoList**.
* З допомогою структурної директиви **ngFor** вивести список **todoList**.
* Додати кнопку **show/hide details** та кнопку **delete**.
* Показувати "No Data" якщо **todoList** відсутній.
* Виконані todo відобразити перекресленеми (з допомогою CSS).
* Додати іконки чекбоксів.
* Додати **bootstrap** стилі до списку.

{% tabs %}
{% tab title="todos.component.html" %}
{% code overflow="wrap" lineNumbers="true" %}

```markup
<section class="container app-todos">
  <ul class="list-group list-group-flush todos-list"
      *ngIf="todoList">
    <li class="list-group-item todos-item"
        *ngFor="let item of todoList">
      <header class="todo-header">
        <div class="d-flex">
          <i class="material-icons check-box">
            {{ item.isDone ? 'check_box' : 'check_box_outline_blank' }}
          </i>

          <h5 [class.is-done]="item.isDone">
            {{item.title}}
          </h5>
        </div>

        <div class="todo-btn-group">
          <button class="btn btn-primary"
                  [disabled]="!item.description">show/hide details</button>

          <button class="btn btn-danger">del</button>
        </div>
      </header>

      <div class="todo-description">
        {{item.description}}
      </div>
    </li>
  </ul>

  <div class="text-center"
       *ngIf="!todoList">
    <p>No Data.</p>
  </div>
</section>
```

{% endcode %}
{% endtab %}

{% tab title="todos.component.css" %}
{% code overflow="wrap" lineNumbers="true" %}

```css
.is-done {
    text-decoration: line-through;
}

.todo-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.check-box {
  margin-right: 15px;
  cursor: pointer;
}

.todo-btn-group button:not(:last-child) {
  margin-right: 5px;
}

.todo-description {
  padding: 10px 0px;
}
```

{% endcode %}
{% endtab %}

{% tab title="todos.component.ts" %}
{% code overflow="wrap" lineNumbers="true" %}

```typescript
import { Component, OnInit } from '@angular/core';
import { Todo } from 'src/app/core/interfaces';

@Component({
  selector: 'app-todos',
  templateUrl: './todos.component.html',
  styleUrls: ['./todos.component.scss']
})
export class TodosComponent implements OnInit {
  todoList: Array<Todo>;
  
  constructor() {
  }
  
  ngOnInit() {
    this.todoList = todoData;
  }
}

const todoData = [{
  id: 1,
  title: 'Learn JS',
  description: '',
  isDone: true
  }, {
  id: 2,
  title: 'Learn Angular',
  description: 'Test description text',
  isDone: false
}];

```

{% endcode %}
{% endtab %}
{% endtabs %}

Приклад дизайну.

## Самостійна робота.

* Todo List має бути адаптивним. Адекватно відображатися на екранах мобільних телефонів, планшетів та ноутбуків. Діапазон ширини дисплея від 320px до 1980px.
* Показувати "Todo list is empty. Please create your first todo." якщо **todoList** пустий.
* Створити компоненту **todo-item** в папці **todos**.
