【Angular】드롭다운 항목 추가 및 변경

17262 단어 AngularAngular8

TL;DR



Reactive Forms를 사용하면 행복할 수 있었다.

실현하고 싶은 것


  • 드롭 다운은 서버 API를 통해 DB에서 얻은 내용을 표시합니다.
  • 마찬가지로 서버 API를 통해 드롭 다운 항목을 추가 및 변경합니다.
  • 추가 후 추가 된 항목을 변경 한 후 변경된 항목을 선택 상태로 만듭니다.



    환경



    node.js


    root@user:/app/my-app# node --version
    v12.7.0
    

    Angular



    package.json
    "dependencies": {
        "@angular/animations": "~8.0.0",
        "@angular/common": "~8.0.0",
        "@angular/compiler": "~8.0.0",
        "@angular/core": "~8.0.0",
        "@angular/forms": "~8.0.0",
        "@angular/platform-browser": "~8.0.0",
        "@angular/platform-browser-dynamic": "~8.0.0",
        "@angular/router": "~8.0.0"
    }
    

    소스 코드



    모듈



    ReactiveFormsModule을 가져옵니다.

    app.module.ts
    import { ReactiveFormsModule } from '@angular/forms';
    
    @NgModule({
      imports: [
        // other imports ...
        ReactiveFormsModule
      ]
    export class AppModule {}
    

    구성요소



    app.component.ts
    import { Component, OnInit } from '@angular/core';
    import { Hero, HeroService } from '../hero.service';
    import { FormControl } from '@angular/forms';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      heroes: Hero[]; // ドロップダウン表示リスト
      selectedHeroControl = new FormControl();
    
      // オブジェクト配列を扱う場合はコンペア関数を実装する必要がある
      compareHero(hero1: Hero, hero2: Hero): boolean {
        return hero1.id === hero2.id;
      }
    
      constructor(private heroService: HeroService) {}
    
      async ngOnInit() {
        this.heroes = await this.heroService.getHeroes().toPromise();
        // ドロップダウンの初期値を設定
        this.selectedHeroControl = new FormControl(this.heroes[0]);
      }
    
      async onClickAddHero(name: string) {
        const addHero = await this.heroService
          .addHero({ name } as Hero)
          .toPromise();
        this.heroes = await this.heroService.getHeroes().toPromise();
        // 追加したHeroを選択状態にする
        this.selectedHeroControl.setValue(addHero);
      }
    
      async onClickUpdateHero(name: string) {
        const updateHero = new Hero(this.selectedHeroControl.value.id, name);
        const updatedHero = await this.heroService
          .updateHero(updateHero)
          .toPromise();
        this.heroes = await this.heroService.getHeroes().toPromise();
        // 変更したHeroを選択状態にする
        this.selectedHeroControl.setValue(updatedHero);
      }
    }
    

    템플릿



    app.component.html
    <select [formControl]="selectedHeroControl" [compareWith]="compareHero">
      <option [ngValue]="hero" *ngFor="let hero of heroes">{{ hero.name }}</option>
    </select>
    <div>
      <label
        >Hero name:
        <input type="text" #heroName />
      </label>
      <button (click)="onClickAddHero(heroName.value)">追加</button>
      <button (click)="onClickUpdateHero(heroName.value)">更新</button>
    </div>
    

    서비스



    자세한 것은 할애.

    hero.service.ts
    import { Injectable } from '@angular/core';
    import { Observable} from 'rxjs';
    
    export class Hero {
      id: number;
      name: string;
    
      constructor(id: number, name: string) {
        this.id = id;
        this.name = name;
      }
    }
    
    @Injectable({
      providedIn: 'root'
    })
    export class HeroService {
      getHeroes(): Observable<Hero[]> {
        // サーバAPIをCallし、取得した一覧を返す
      }
    
      addHero(hero: Hero): Observable<Hero> {
        // サーバAPIをCallし、追加したオブジェクトを返す
      }
    
      updateHero(hero: Hero): Observable<Hero> {
        // サーバAPIをCallし、更新したオブジェクトを返す
      }
    }
    

    보충 설명



    비교 함수



    Angular는 옵션을 고유하게 식별하기 위해 객체 ID를 사용합니다. 변경시에, 현재 표시하고 있는 항목과, 변경 후에 서버 API로부터 재취득한 항목 추가한 항목의 오브젝트 ID는 다르기 때문에, 일치 여부의 비교 알고리즘을 구현할 필요가 있다.

    app.component.ts
    export class AppComponent {
      compareHero(hero1: Hero, hero2: Hero): boolean {
        return hero1.id === hero2.id;
      }
    }
    

    app.component.html
    <select [compareWith]="compareHero">
    

    드롭다운 변경을 감지하는 방법



    FromControl.valueChanges를 사용합니다.

    app.component.ts
      async ngOnInit() {
        this.selectedHeroControl.valueChanges.subscribe(hero => {
          console.log(`Selected Hero: ${hero.name}`);
        });
      }
    }
    

    참고


  • Reactive Forms
  • SelectControlValueAccessor
  • 좋은 웹페이지 즐겨찾기