Как ускорить разработку приложения Angular с помощью ngModel.

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

Любая работа с полем ввода (да, эти пользователи сайта постоянно пытаются ввести какие-то данные) заставляет нас писать обработчики для получения данных. Иногда от нас требуется отправить данные, и для этого нам также необходимо создать обработчик.

Было бы здорово не подписываться на одно и то же действие каждый раз, чтобы отвечать на него. Встроенная директива ngModel позволяет нам избежать всего этого ненужного написания.

Что это за директива и как с ней справиться? В чем его преимущества и опасности? Давайте погрузимся в это и разберемся.

NgModel

Несколько скучных фактов.
NgModel - это директива, которая разрешает двустороннюю привязку данных. Самый простой способ использовать его - просто определить для него переменную, с которой он будет работать и где мы хотим видеть результаты:

<input [(ngModel)]="name">
<div>Input value {{name}}</div>

Хорошо, давай немного притормозим! Что это за скобки и откуда взялась эта переменная?

Это просто. Мы определяем переменную внутри нашего компонента, которая будет доступна внутри шаблона.

import { Component } from '@angular/core';

@Component({
  selector: 'example',
  template: `
    <input [value]="name" (input)="name = $event.target.value">
    <div>Input value {{name}}</div>
  `,
})
export class SimpleBindingComponent {
  name = '';
}

Теперь, когда все ясно, давайте поговорим о скобках вокруг параметров. Они созданы не для красоты, как может показаться на первый взгляд.

Это наш двусторонний механизм привязки. [] вокруг любого атрибута или директивы позволяет вам передать значение этому атрибуту. () позволяет вам подписаться на события, сгенерированные внутри нашей директивы, или на любые другие события, такие как щелчок.

...

<input [value]="value" [readonly]="isReadonly" (input)="valueChange()" (click)="clickMe()">

...

Скобки, привязки, компоненты, пока все становится все сложнее и запутаннее. А теперь давайте попробуем без всей этой теории!

import { Component } from '@angular/core';
import { YourApiService } from './your-api.service';

@Component({
  selector: 'example',
  template: `
    <input [(ngModel)]="name">
    <div>Input value {{name}}</div>

    <button type="submit" (submit)="submit()"></button>
  `,
})
export class NgModelComponent {
  name = 'Susan';

  constructor(private yourApiService: YourApiService) {}

  submit() {
    this.yourApiService.submit(this.name);
  }
}

Всего пара строк и наши данные готовы. Все готово; вам просто нужно отправить его на сервер. Но зачем все эти хлопоты, если мы можем сделать свою привязку. Теперь давайте возьмем и присвоим значение нашей переменной.

@Component({
  selector: 'custom-binding',
  template: `
    <button (click)="setRed()">Set red</button>
    <button (click)="setGreen()">Set green</button>
      <div>Input value {{color}}</div>
  `
})
export class CustomBindingComponent {
  color = '';
@Output()
  currentColorChange = new EventEmitter();
@Input()
  get currentColor() {
    return this.color;
  }
set currentColor(value) {
    this.color = value;
    this.currentColorChange.emit(this.color);
  }
setRed() {
    this.currentColor = 'Red';
  }
setGreen() {
    this.currentColor = 'Green';
  }
}
...
<custom-binding [(currentColor)]="someValue"></custom-binding>
<div>{{someValue}}</div>
...

NgModel - это не только связанные данные. Работая с тегом формы, мы также можем получить дополнительную информацию, например, достоверность введенных данных.

import { Component } from '@angular/core';
import { YourApiService } from './your-api.service';

@Component({
  selector: 'example',
  template: `
    <input [(ngModel)]="name" #ctrl="ngModel" required>
    <div>Input value {{name}}</div>
    <div>Input valid {{ctrl.valid}}</div>

    <button type="submit" [disabled]="ctrl.invalid" (submit)="submit()"></button>
  `,
})
export class NgModelComponent {
  name = 'Susan';

  constructor(private yourApiService: YourApiService) {}

  submit() {
    this.yourApiService.submit(this.name);
  }
}

Таким образом, мы видим, что работа с ngModel может дать вам гибкий и удобный механизм управления всей формой (в Angular есть отдельный механизм для управления формами, но мы рассмотрим его в другой раз). А теперь займемся тем, о чем идет речь. Создайте форму.

import { Component } from '@angular/core';
import { NgForm } from '@angular/forms';
import { YourApiService } from './your-api.service';

@Component({
  selector: 'example',
  template: `
    <form #f="ngForm" (ngSubmit)="onSubmit(f)" novalidate>
      <input name="first" ngModel required #first="ngModel">
      <input name="last" ngModel>
      <button>Submit</button>
    </form>

    <p>First name value: {{ first.value }}</p>
    <p>First name valid: {{ first.valid }}</p>
    <p>Form value: {{ f.value | json }}</p>
    <p>Form valid: {{ f.valid }}</p>
  `,
})
export class SimpleFormComponent {
  onSubmit(f: NgForm) {
    if (f.valid) {
      this.yourApiService.submit(f.value);
    }
  }
}

Заключение

Работать с моделью данных Angular проще и удобнее, чем кажется на первый взгляд. NgModel позволяет нам легко связать данные шаблона и компонента, используя всего пару строк кода. Этот мощный и простой механизм может значительно упростить и ускорить разработку вашего приложения. И да, неплохо бы не забыть добавить его в раздел импорта модуля. Хотя современные IDE, скорее всего, предложат сделать это автоматически.

У вас есть вопросы? Смело спрашивайте здесь!