Работа с формами

Модуль FormsModule и директива NgModel

Последнее обновление: 15.11.2023

Для взаимодействия с пользователем в веб-приложениях, как правило применяются формы. Для работы с функциональностью форм компоненты импортируют модуль FormsModule с помощью параметра imports:< Angular прежде чем использовать формы в компонентах, нам надо импортировать в главном модуле AppModule модуль FormsModule, который позволяет работать с формами:

import { Component} from "@angular/core";
import { FormsModule } from "@angular/forms";

@Component({
    selector: "my-app",
    standalone: true,
    imports: [FormsModule], // для работы с формами импортируем FormsModule
    template: ``
})
export class AppComponent{ }

Кроме того, в файле конфигурации приложения package.json среди списка используемых зависимостей должен быть указан пакет "angular/forms":

{
    "name": "helloapp",
    "version": "1.0.0",
    "description": "First Angular 17 Project",
    "author": "Eugene Popov metanit.com",
    "scripts": {
        // команды angular cli
    },
    "dependencies": {
        "@angular/forms": "~17.0.0",
		// остальные пакеты
    },
    "devDependencies": {
        
		// остальные пакеты
    }
}

При работе с формами ключевым моментом является использование директивы NgModel. Эта директива с помощью переданной модели создает объект FormControl и привязывает эту модель к созданному элементу формы. Объект FormControl отслеживает значение модели, а также отвечает за валидацию этого значения и взаимодействие с пользователем.

Данная директива принимает переданную ей модель в качестве входного свойства. Причем мы можем использовать как однонаправленную, так и двунаправленную привязку.

Если нам надо просто вывести значение модели в поле ввода, то можно ограничиться и однонаправленной привязкой:

<input name="title" [ngModel]="title" />

Это обычная привязка свойства, где в качестве модели используется некоторое свойство title, определенное в классе компонента.

Если нам надо отслеживать изменение введенных данных, то мы можем использовать двунаправленную привязку:

<input name="title" [(ngModel)]="title" />

Рассмотрим применение NgModel на примере. Возьмем проект с базовой структурой:

NgModel и FormControl в Angular

Определим в файле app.component.ts следующий компонент:

import { Component} from "@angular/core";
import { FormsModule } from "@angular/forms";

class User{
    constructor(public name: string, 
                public age: number, 
                public company: string)
    { }
}
 
@Component({
    selector: "my-app",
    standalone: true,
    imports: [FormsModule], // для работы с формами импортируем FormsModule
    template: `<div> 
                    <p>
                        <label>Имя пользователя</label><br>
                        <input name="name" [(ngModel)]="name" />
                    </p>
                    <p>
                        <label>Возраст</label><br>
                        <input type="number" name="age" [(ngModel)]="age" />
                    </p>
                    <p>
                        <label>Место работы</label><br>
                        <select name="company" [(ngModel)]="company">
                        @for(comp of companies; track $index){
                            <option [value]="comp">
                                {{comp}}
                            </option>
                        }
                        </select>
                    </p>
                    <button (click)="addUser()">Добавить</button>
              </div>
              <div>
                <h3>Добавленные элементы</h3>
                <ul>
                @for(u of users; track $index){
                    <li>{{u.name}} ({{u.company}}) - {{u.age}}</li>
                }
                </ul>
              </div>`
})
export class AppComponent { 
 
    name: string = "";
    age: number = 18;
    company: string = "";
     
    users: User[] = [];
    companies: string[] = ["Apple", "Microsoft", "Google", "Jetbrains"];
     
    addUser(){
        this.users.push(new User(this.name, this.age, this.company));
    }
}

Для представления данных здесь определен класс User, в котором есть три свойства. Класс компонента содержит массив объектов User. С помощью метода addUser() в этот массив добавляется новый объект.

Для добавления данных в шаблоне определены три поля ввода. В каждом поле определены директивы типа [(ngModel)]="namee". Тем самым фактически определяются некоторые значения, которые привязаны к этим полям. В обработчике нажатия кнопки вызывается метод addUser(), в который передаются эти значения.

В конце шаблона добавленные данные из массива users выводятся на страницу:

Работа с формами и NgModel в Angular

Все три поля привязаны к отдельным значениям, которые существуют сами по себе. Но мы можем пойти дальше и определить для формы ввода отдельную модель, которая будет инкапсулировать эти значения:

import { Component} from "@angular/core";
import { FormsModule } from "@angular/forms";

class User{
    constructor(public name: string, 
                public age: number, 
                public company: string)
    { }
}
 
@Component({
    selector: "my-app",
    standalone: true,
    imports: [FormsModule], // для работы с формами импортируем FormsModule
    template: `<div> 
                    <p>
                        <label>Имя пользователя</label><br>
                        <input name="name" [(ngModel)]="newUser.name" />
                    </p>
                    <p>
                        <label>Возраст</label><br>
                        <input type="number" name="age" [(ngModel)]="newUser.age" />
                    </p>
                    <p>
                        <label>Место работы</label><br>
                        <select name="company" [(ngModel)]="newUser.company">
                        @for(comp of companies; track $index){
                            <option [value]="comp">
                                {{comp}}
                            </option>
                        }
                        </select>
                    </p>
                    <button (click)="addUser()">Добавить</button>
              </div>
              <div>
                <h3>Добавленные элементы</h3>
                <ul>
                @for(u of users; track $index){
                    <li>{{u.name}} ({{u.company}}) - {{u.age}}</li>
                }
                </ul>
              </div>`
})
export class AppComponent { 
 
    newUser = new User("", 18, "Google")
     
    users: User[] = [];
    companies: string[] = ["Apple", "Microsoft", "Google", "Jetbrains"];
     
    addUser(){
        this.users.push({...this.newUser});
    }
}

Для полей ввода здесь создана отдельная переменная newUser, к свойствам которой привязаны поля ввода. Стоит также обратить внимание на то, как добавляется новый объект в массив users - здесь не добавляется напрямую переменная newUser, а создается отдельный объект, который инициализируется значениями из переменной newUser. А в остальном результат будет тем же, что и в предыдущем примере.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850