Angular uygulamanıza form ekleme

Bu eğitim dersi, bir Angular uygulamasına kullanıcı verilerini toplayan bir formun nasıl ekleneceğini gösterir. Bu ders, çalışan bir Angular uygulamasıyla başlar ve ona nasıl form ekleneceğini gösterir.

Formun topladığı veriler yalnızca uygulamanın servisine gönderilir ve bu servis verileri tarayıcının konsoluna yazar. Form verilerini göndermek ve almak için bir REST API kullanmak bu derste ele alınmamaktadır.

IMPORTANT: Eğitimin bu adımı için yerel ortamınızı kullanmanızı öneriyoruz.

Neler öğreneceksiniz

  • Uygulamanızda, kullanıcıların uygulamanızın servisine gönderilen verileri girebileceği bir form var.
  • Servis, formdaki verileri tarayıcının konsol günlüğüne yazar.
  1. Form verilerini göndermek için bir metot ekleyin

    Bu adım, uygulamanızın servisine, form verilerini verilerin hedefine göndermek için alan bir metot ekler. Bu örnekte, metot formdaki verileri tarayıcının konsol günlüğüne yazar.

    IDE'nizin Edit bölmesinde:

    1. src/app/housing.service.ts dosyasında, HousingService sınıfı içine bu metodu sınıf tanımının en altına yapıştırın.

      Submit method in src/app/housing.service.ts

      import {Injectable} from '@angular/core';
      import {HousingLocationInfo} from './housinglocation';
      
      @Injectable({
        providedIn: 'root',
      })
      export class HousingService {
        readonly baseUrl = 'https://angular.dev/assets/images/tutorials/common';
      
        protected housingLocationList: HousingLocationInfo[] = [
          {
            id: 0,
            name: 'Acme Fresh Start Housing',
            city: 'Chicago',
            state: 'IL',
            photo: `${this.baseUrl}/bernard-hermant-CLKGGwIBTaY-unsplash.jpg`,
            availableUnits: 4,
            wifi: true,
            laundry: true,
          },
          {
            id: 1,
            name: 'A113 Transitional Housing',
            city: 'Santa Monica',
            state: 'CA',
            photo: `${this.baseUrl}/brandon-griggs-wR11KBaB86U-unsplash.jpg`,
            availableUnits: 0,
            wifi: false,
            laundry: true,
          },
          {
            id: 2,
            name: 'Warm Beds Housing Support',
            city: 'Juneau',
            state: 'AK',
            photo: `${this.baseUrl}/i-do-nothing-but-love-lAyXdl1-Wmc-unsplash.jpg`,
            availableUnits: 1,
            wifi: false,
            laundry: false,
          },
          {
            id: 3,
            name: 'Homesteady Housing',
            city: 'Chicago',
            state: 'IL',
            photo: `${this.baseUrl}/ian-macdonald-W8z6aiwfi1E-unsplash.jpg`,
            availableUnits: 1,
            wifi: true,
            laundry: false,
          },
          {
            id: 4,
            name: 'Happy Homes Group',
            city: 'Gary',
            state: 'IN',
            photo: `${this.baseUrl}/krzysztof-hepner-978RAXoXnH4-unsplash.jpg`,
            availableUnits: 1,
            wifi: true,
            laundry: false,
          },
          {
            id: 5,
            name: 'Hopeful Apartment Group',
            city: 'Oakland',
            state: 'CA',
            photo: `${this.baseUrl}/r-architecture-JvQ0Q5IkeMM-unsplash.jpg`,
            availableUnits: 2,
            wifi: true,
            laundry: true,
          },
          {
            id: 6,
            name: 'Seriously Safe Towns',
            city: 'Oakland',
            state: 'CA',
            photo: `${this.baseUrl}/phil-hearing-IYfp2Ixe9nM-unsplash.jpg`,
            availableUnits: 5,
            wifi: true,
            laundry: true,
          },
          {
            id: 7,
            name: 'Hopeful Housing Solutions',
            city: 'Oakland',
            state: 'CA',
            photo: `${this.baseUrl}/r-architecture-GGupkreKwxA-unsplash.jpg`,
            availableUnits: 2,
            wifi: true,
            laundry: true,
          },
          {
            id: 8,
            name: 'Seriously Safe Towns',
            city: 'Oakland',
            state: 'CA',
            photo: `${this.baseUrl}/saru-robert-9rP3mxf8qWI-unsplash.jpg`,
            availableUnits: 10,
            wifi: false,
            laundry: false,
          },
          {
            id: 9,
            name: 'Capital Safe Towns',
            city: 'Portland',
            state: 'OR',
            photo: `${this.baseUrl}/webaliser-_TPTXZd9mOo-unsplash.jpg`,
            availableUnits: 6,
            wifi: true,
            laundry: true,
          },
        ];
      
        getAllHousingLocations(): HousingLocationInfo[] {
          return this.housingLocationList;
        }
      
        getHousingLocationById(id: number): HousingLocationInfo | undefined {
          return this.housingLocationList.find((housingLocation) => housingLocation.id === id);
        }
        submitApplication(firstName: string, lastName: string, email: string) {
          console.log(
            `Homes application received: firstName: ${firstName}, lastName: ${lastName}, email: ${email}.`,
          );
        }
      }
      
    2. Uygulamanın hatasız derlendiğini doğrulayın. Bir sonraki adıma geçmeden önce tüm hataları düzeltin.

  2. Ayrıntılar sayfasına form fonksiyonlarını ekleyin

    Bu adım, formun etkileşimlerini yöneten kodu ayrıntılar sayfasına ekler.

    IDE'nizin Edit bölmesinde, src/app/details/details.ts dosyasında:

    1. Dosyanın en üstündeki import ifadelerinden sonra, Angular form sınıflarını içe aktarmak için aşağıdaki kodu ekleyin.

      Forms imports in src/app/details/details.ts

      import {Component, inject} from '@angular/core';
      import {ActivatedRoute} from '@angular/router';
      import {HousingService} from '../housing.service';
      import {HousingLocationInfo} from '../housinglocation';
      import {FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms';
      
      @Component({
        selector: 'app-details',
        imports: [ReactiveFormsModule],
        template: `
          <article>
            <img
              class="listing-photo"
              [src]="housingLocation?.photo"
              alt="Exterior photo of {{ housingLocation?.name }}"
              crossorigin
            />
            <section class="listing-description">
              <h2 class="listing-heading">{{ housingLocation?.name }}</h2>
              <p class="listing-location">{{ housingLocation?.city }}, {{ housingLocation?.state }}</p>
            </section>
            <section class="listing-features">
              <h2 class="section-heading">About this housing location</h2>
              <ul>
                <li>Units available: {{ housingLocation?.availableUnits }}</li>
                <li>Does this location have wifi: {{ housingLocation?.wifi }}</li>
                <li>Does this location have laundry: {{ housingLocation?.laundry }}</li>
              </ul>
            </section>
            <section class="listing-apply">
              <h2 class="section-heading">Apply now to live here</h2>
              <form [formGroup]="applyForm" (submit)="submitApplication()">
                <label for="first-name">First Name</label>
                <input id="first-name" type="text" formControlName="firstName" />
      
                <label for="last-name">Last Name</label>
                <input id="last-name" type="text" formControlName="lastName" />
      
                <label for="email">Email</label>
                <input id="email" type="email" formControlName="email" />
                <button type="submit" class="primary">Apply now</button>
              </form>
            </section>
          </article>
        `,
        styleUrls: ['./details.css'],
      })
      export class Details {
        route: ActivatedRoute = inject(ActivatedRoute);
        housingService = inject(HousingService);
        housingLocation: HousingLocationInfo | undefined;
        applyForm = new FormGroup({
          firstName: new FormControl(''),
          lastName: new FormControl(''),
          email: new FormControl(''),
        });
      
        constructor() {
          const housingLocationId = parseInt(this.route.snapshot.params['id'], 10);
          this.housingLocation = this.housingService.getHousingLocationById(housingLocationId);
        }
        submitApplication() {
          this.housingService.submitApplication(
            this.applyForm.value.firstName ?? '',
            this.applyForm.value.lastName ?? '',
            this.applyForm.value.email ?? '',
          );
        }
      }
      
    2. Details dekoratörü meta verilerinde, imports özelliğini aşağıdaki kodla güncelleyin:

      imports directive in src/app/details/details.ts

      import {Component, inject} from '@angular/core';
      import {ActivatedRoute} from '@angular/router';
      import {HousingService} from '../housing.service';
      import {HousingLocationInfo} from '../housinglocation';
      import {FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms';
      
      @Component({
        selector: 'app-details',
        imports: [ReactiveFormsModule],
        template: `
          <article>
            <img
              class="listing-photo"
              [src]="housingLocation?.photo"
              alt="Exterior photo of {{ housingLocation?.name }}"
              crossorigin
            />
            <section class="listing-description">
              <h2 class="listing-heading">{{ housingLocation?.name }}</h2>
              <p class="listing-location">{{ housingLocation?.city }}, {{ housingLocation?.state }}</p>
            </section>
            <section class="listing-features">
              <h2 class="section-heading">About this housing location</h2>
              <ul>
                <li>Units available: {{ housingLocation?.availableUnits }}</li>
                <li>Does this location have wifi: {{ housingLocation?.wifi }}</li>
                <li>Does this location have laundry: {{ housingLocation?.laundry }}</li>
              </ul>
            </section>
            <section class="listing-apply">
              <h2 class="section-heading">Apply now to live here</h2>
              <form [formGroup]="applyForm" (submit)="submitApplication()">
                <label for="first-name">First Name</label>
                <input id="first-name" type="text" formControlName="firstName" />
      
                <label for="last-name">Last Name</label>
                <input id="last-name" type="text" formControlName="lastName" />
      
                <label for="email">Email</label>
                <input id="email" type="email" formControlName="email" />
                <button type="submit" class="primary">Apply now</button>
              </form>
            </section>
          </article>
        `,
        styleUrls: ['./details.css'],
      })
      export class Details {
        route: ActivatedRoute = inject(ActivatedRoute);
        housingService = inject(HousingService);
        housingLocation: HousingLocationInfo | undefined;
        applyForm = new FormGroup({
          firstName: new FormControl(''),
          lastName: new FormControl(''),
          email: new FormControl(''),
        });
      
        constructor() {
          const housingLocationId = parseInt(this.route.snapshot.params['id'], 10);
          this.housingLocation = this.housingService.getHousingLocationById(housingLocationId);
        }
        submitApplication() {
          this.housingService.submitApplication(
            this.applyForm.value.firstName ?? '',
            this.applyForm.value.lastName ?? '',
            this.applyForm.value.email ?? '',
          );
        }
      }
      
    3. Details sınıfında, constructor() metodundan önce form nesnesini oluşturmak için aşağıdaki kodu ekleyin.

      template directive in src/app/details/details.ts

      import {Component, inject} from '@angular/core';
      import {ActivatedRoute} from '@angular/router';
      import {HousingService} from '../housing.service';
      import {HousingLocationInfo} from '../housinglocation';
      import {FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms';
      
      @Component({
        selector: 'app-details',
        imports: [ReactiveFormsModule],
        template: `
          <article>
            <img
              class="listing-photo"
              [src]="housingLocation?.photo"
              alt="Exterior photo of {{ housingLocation?.name }}"
              crossorigin
            />
            <section class="listing-description">
              <h2 class="listing-heading">{{ housingLocation?.name }}</h2>
              <p class="listing-location">{{ housingLocation?.city }}, {{ housingLocation?.state }}</p>
            </section>
            <section class="listing-features">
              <h2 class="section-heading">About this housing location</h2>
              <ul>
                <li>Units available: {{ housingLocation?.availableUnits }}</li>
                <li>Does this location have wifi: {{ housingLocation?.wifi }}</li>
                <li>Does this location have laundry: {{ housingLocation?.laundry }}</li>
              </ul>
            </section>
            <section class="listing-apply">
              <h2 class="section-heading">Apply now to live here</h2>
              <form [formGroup]="applyForm" (submit)="submitApplication()">
                <label for="first-name">First Name</label>
                <input id="first-name" type="text" formControlName="firstName" />
      
                <label for="last-name">Last Name</label>
                <input id="last-name" type="text" formControlName="lastName" />
      
                <label for="email">Email</label>
                <input id="email" type="email" formControlName="email" />
                <button type="submit" class="primary">Apply now</button>
              </form>
            </section>
          </article>
        `,
        styleUrls: ['./details.css'],
      })
      export class Details {
        route: ActivatedRoute = inject(ActivatedRoute);
        housingService = inject(HousingService);
        housingLocation: HousingLocationInfo | undefined;
        applyForm = new FormGroup({
          firstName: new FormControl(''),
          lastName: new FormControl(''),
          email: new FormControl(''),
        });
      
        constructor() {
          const housingLocationId = parseInt(this.route.snapshot.params['id'], 10);
          this.housingLocation = this.housingService.getHousingLocationById(housingLocationId);
        }
        submitApplication() {
          this.housingService.submitApplication(
            this.applyForm.value.firstName ?? '',
            this.applyForm.value.lastName ?? '',
            this.applyForm.value.email ?? '',
          );
        }
      }
      

      Angular'da FormGroup ve FormControl, form oluşturmanızı sağlayan türlerdir. FormControl türü, varsayılan bir değer sağlayabilir ve form verilerini şekillendirebilir. Bu örnekte firstName bir string'dir ve varsayılan değeri boş dizedir.

    4. Details sınıfında, constructor() metodundan sonra Şimdi Başvur tıklamasını yönetmek için aşağıdaki kodu ekleyin.

      template directive in src/app/details/details.ts

      import {Component, inject} from '@angular/core';
      import {ActivatedRoute} from '@angular/router';
      import {HousingService} from '../housing.service';
      import {HousingLocationInfo} from '../housinglocation';
      import {FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms';
      
      @Component({
        selector: 'app-details',
        imports: [ReactiveFormsModule],
        template: `
          <article>
            <img
              class="listing-photo"
              [src]="housingLocation?.photo"
              alt="Exterior photo of {{ housingLocation?.name }}"
              crossorigin
            />
            <section class="listing-description">
              <h2 class="listing-heading">{{ housingLocation?.name }}</h2>
              <p class="listing-location">{{ housingLocation?.city }}, {{ housingLocation?.state }}</p>
            </section>
            <section class="listing-features">
              <h2 class="section-heading">About this housing location</h2>
              <ul>
                <li>Units available: {{ housingLocation?.availableUnits }}</li>
                <li>Does this location have wifi: {{ housingLocation?.wifi }}</li>
                <li>Does this location have laundry: {{ housingLocation?.laundry }}</li>
              </ul>
            </section>
            <section class="listing-apply">
              <h2 class="section-heading">Apply now to live here</h2>
              <form [formGroup]="applyForm" (submit)="submitApplication()">
                <label for="first-name">First Name</label>
                <input id="first-name" type="text" formControlName="firstName" />
      
                <label for="last-name">Last Name</label>
                <input id="last-name" type="text" formControlName="lastName" />
      
                <label for="email">Email</label>
                <input id="email" type="email" formControlName="email" />
                <button type="submit" class="primary">Apply now</button>
              </form>
            </section>
          </article>
        `,
        styleUrls: ['./details.css'],
      })
      export class Details {
        route: ActivatedRoute = inject(ActivatedRoute);
        housingService = inject(HousingService);
        housingLocation: HousingLocationInfo | undefined;
        applyForm = new FormGroup({
          firstName: new FormControl(''),
          lastName: new FormControl(''),
          email: new FormControl(''),
        });
      
        constructor() {
          const housingLocationId = parseInt(this.route.snapshot.params['id'], 10);
          this.housingLocation = this.housingService.getHousingLocationById(housingLocationId);
        }
        submitApplication() {
          this.housingService.submitApplication(
            this.applyForm.value.firstName ?? '',
            this.applyForm.value.lastName ?? '',
            this.applyForm.value.email ?? '',
          );
        }
      }
      

      Bu düğme henüz mevcut değil - bir sonraki adımda ekleyeceksiniz. Yukarıdaki kodda, FormControl'ler null döndürebilir. Bu kod, değer null ise varsayılan olarak boş dize kullanmak için nullish birleştirme operatörünü kullanır.

    5. Uygulamanın hatasız derlendiğini doğrulayın. Bir sonraki adıma geçmeden önce tüm hataları düzeltin.

  3. Ayrıntılar sayfasına formun işaretlemesini ekleyin

    Bu adım, formu görüntüleyen işaretlemeyi ayrıntılar sayfasına ekler.

    IDE'nizin Edit bölmesinde, src/app/details/details.ts dosyasında:

    1. Details dekoratörü meta verilerinde, formun işaretlemesini eklemek için template HTML'ini aşağıdaki kodla eşleşecek şekilde güncelleyin.

      template directive in src/app/details/details.ts

      import {Component, inject} from '@angular/core';
      import {ActivatedRoute} from '@angular/router';
      import {HousingService} from '../housing.service';
      import {HousingLocationInfo} from '../housinglocation';
      import {FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms';
      
      @Component({
        selector: 'app-details',
        imports: [ReactiveFormsModule],
        template: `
          <article>
            <img
              class="listing-photo"
              [src]="housingLocation?.photo"
              alt="Exterior photo of {{ housingLocation?.name }}"
              crossorigin
            />
            <section class="listing-description">
              <h2 class="listing-heading">{{ housingLocation?.name }}</h2>
              <p class="listing-location">{{ housingLocation?.city }}, {{ housingLocation?.state }}</p>
            </section>
            <section class="listing-features">
              <h2 class="section-heading">About this housing location</h2>
              <ul>
                <li>Units available: {{ housingLocation?.availableUnits }}</li>
                <li>Does this location have wifi: {{ housingLocation?.wifi }}</li>
                <li>Does this location have laundry: {{ housingLocation?.laundry }}</li>
              </ul>
            </section>
            <section class="listing-apply">
              <h2 class="section-heading">Apply now to live here</h2>
              <form [formGroup]="applyForm" (submit)="submitApplication()">
                <label for="first-name">First Name</label>
                <input id="first-name" type="text" formControlName="firstName" />
      
                <label for="last-name">Last Name</label>
                <input id="last-name" type="text" formControlName="lastName" />
      
                <label for="email">Email</label>
                <input id="email" type="email" formControlName="email" />
                <button type="submit" class="primary">Apply now</button>
              </form>
            </section>
          </article>
        `,
        styleUrls: ['./details.css'],
      })
      export class Details {
        route: ActivatedRoute = inject(ActivatedRoute);
        housingService = inject(HousingService);
        housingLocation: HousingLocationInfo | undefined;
        applyForm = new FormGroup({
          firstName: new FormControl(''),
          lastName: new FormControl(''),
          email: new FormControl(''),
        });
      
        constructor() {
          const housingLocationId = parseInt(this.route.snapshot.params['id'], 10);
          this.housingLocation = this.housingService.getHousingLocationById(housingLocationId);
        }
        submitApplication() {
          this.housingService.submitApplication(
            this.applyForm.value.firstName ?? '',
            this.applyForm.value.lastName ?? '',
            this.applyForm.value.email ?? '',
          );
        }
      }
      

      Şablon artık bir (submit)="submitApplication()" olay işleyicisi içermektedir. Angular, şablon kodunda olayları tanımlamak için olay adının etrafında parantez sözdizimi kullanır. Eşittir işaretinin sağ tarafındaki kod, bu olay tetiklendiğinde yürütülmesi gereken koddur. Tarayıcı olaylarına ve özel olaylara bağlanabilirsiniz.

    2. Uygulamanın hatasız derlendiğini doğrulayın. Bir sonraki adıma geçmeden önce tüm hataları düzeltin.

      details page with a form for applying to live at this location
  4. Uygulamanızın yeni formunu test edin

    Bu adım, form verileri uygulamaya gönderildiğinde form verilerinin konsol günlüğünde göründüğünü görmek için yeni formu test eder.

    1. IDE'nizin Terminal bölmesinde, ng serve çalışmıyorsa çalıştırın.
    2. Tarayıcınızda, uygulamanızı http://localhost:4200 adresinde açın.
    3. Tarayıcıda uygulamaya sağ tıklayın ve bağlam menüsünden İncele'yi seçin.
    4. Geliştirici araçları penceresinde Konsol sekmesini seçin. Sonraki adımlar için geliştirici araçları penceresinin görünür olduğundan emin olun.
    5. Uygulamanızda:
      1. Bir konut konumu seçin ve ev hakkında ayrıntıları görmek için Learn more tıklayın.
      2. Evin ayrıntılar sayfasında, yeni formu bulmak için en alta kaydırın.
      3. Form alanlarına veri girin - herhangi bir veri olabilir.
      4. Verileri göndermek için Apply now seçin.
    6. Geliştirici araçları penceresinde, form verilerinizi bulmak için günlük çıktısını inceleyin.

SUMMARY: Bu derste, Angular'ın form özelliğini kullanarak uygulamanıza bir form eklediniz ve formda yakalanan verileri bir olay işleyici kullanarak bir bileşene bağladınız.

Bu derste ele alınan konular hakkında daha fazla bilgi için: