Wprowadzenie

Wiązanie jednokierunkowe nie pozwala na odzwierciedlenie zmian szablonu w kodzie napisanym w TypeScript. Rozwiązaniem tego problem jest wiązanie dwukierunkowe, które jest zapewnione przez Angular. Pozwala na aktualizowanie danych z kompomentu do widoku i odwrotnie.

W przypadku wiązania dwukierunkowego synchronizacja danych pomiędzy modelem a widokiem odbywa się automatycznie. Zmiana zawsze znajduje odzwierciedlenie w obu komponentach. Wiązanie dwukierunkowe stanowi połączenie wiązania właściwości oraz zdarzeń.

Składania wiązania przedstawia się w poniższy sposób:

[(ngModel)] = "[właściwość zdefiniowana w komponencie]"  
Adnotacja: aby poprawnie korzystać z tego wiązania musimy włączyć dyrektywę ngModel. Zależy ona pakietu FormsModule, który musimy zaimportować korzystając z tablicy imports w pliku app.module.ts. Spójrzcie na poniższy kod wraz z komentarzami:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
// Importujemy dany pakiet
import {FormsModule} from '@angular/forms';    

import { AppRoutingModule } from './app-routing.module';
import { DashboardComponent } from './Dashboard/dashboard.component';
import { PropertBindingComponent } from './Components/property-binding/property-binding.component';
import { StringInterpolationComponent } from './Components/string-interpolation/string-interpolation.component';
import { EventBindingComponent } from './Components/event-binding/event-binding.component';
import { TwoWayDataBindingComponent } from './Components/two-way-data-binding/two-way-data-binding.component';

@NgModule({
  declarations: [
    DashboardComponent,
    PropertBindingComponent,
    StringInterpolationComponent,
    EventBindingComponent,
    TwoWayDataBindingComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    // Dodajemy do listy modułów z których korzystamy
    FormsModule
  ],
  providers: [],
  bootstrap: [DashboardComponent]
})
export class AppModule { }
Dzięki takiej definicji możemy korzystać z tej funkcjonalności w każdym komponencie.

Przykłady

Samo podejście nie wymaga od nas dużo większego zaangażowania. W pierwszym kroku dodamy oczywiście właściwość w kodzie naszego komponentu:

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

@Component({
  selector: 'app-two-way-data-binding',
  templateUrl: './two-way-data-binding.component.html',
  styleUrls: ['./two-way-data-binding.component.css']
})
export class TwoWayDataBindingComponent {
  text: string = "Witajcie z komponentu!"
}
Po stronie szablonu dodamy definicję odpowiedniego wiązania:
<p>Komponent przeznaczony dla: two-way-data-binding</p>

<input [(ngModel)]="text" style="width:250px">
<br />
<br />
<span>Wprowadzony tekst: {{text}}</span>
A tak prezentuje się działająca aplikacja:

Pierwszy raz styczność z wiązaniem dwukierunkowym miałem, kiedy rozpocząłem swoją pracę z zestawem narzędzi Oracle JET. Od tamtej pory nie potrafię wyobrazić sobie pracy z interfejsem użytkownika bez tej funkcjonalności.

Wystarczy spojrzeć na dowolny formularz do wprowadzania danych w przypadku aplikacji biznesowych – wszelkiej maści nazwy plików, raporty, daty publikacji oraz mnogość wyboru przy użyciu list rozwijalnych. Każda wartość jest kontorolowana przez swoją właściwość (możemy zdefiniować w prosty sposób zestaw danych domyślnych) a wraz ze zmianą danych na formularzu ulegają zmienie wartości naszych właściwości – dzięki temu przy zapisywaniu danych mamy dostęp do każdej z nich.

W kolejnym wpisie będę omawiał wspomniane powyżej formularze – pokaże nieco bardziej skomplikowany przykład z użyciem wielu elementów oraz proces “zapisywania" tych danych – zobaczycie jak łatwo uzyskać do nich dostęp.