깜놀하는 해므찌로

Angular Radio Component 생성 및 활용 예시 본문

IT

Angular Radio Component 생성 및 활용 예시

agnusdei1207 2023. 6. 27. 15:04
반응형
SMALL
/* option */

// 템플릿

<label [for]="value" (click)="selected$.emit(value)">
  <div class="flex gap-2 items-center cursor-pointer">
    <div class="text-sm text-gray-500 flex">
      <ng-content />
    </div>
    <input
      class="cursor-pointer w-4 h-4 appearance-none ring-gray-300 bg-gray-300 rounded-full ring-2 ring-offset-2 indeterminate:ring-gray-300 checked:ring-primary checked:bg-primary transition-all"
      type="radio"
      [id]="value"
      [name]="name"
      [value]="value"
      [checked]="checked"
      [disabled]="disabled"
    />
  </div>
</label>

// 컴포넌트

import { Component, EventEmitter, Input, Output } from '@angular/core';

@Component({
  selector: 'app-radio-option',
  templateUrl: './radio-option.component.html',
  styleUrls: ['./radio-option.component.scss'],
  standalone: true,
})
export class RadioOptionComponent {
  @Output() selected$: EventEmitter<any> = new EventEmitter<any>();

  @Input() value: any;
  @Input() disabled: boolean = false;
  @Input() name!: string;
  @Input() checked: boolean = false;
}
/* radio */

// 템플릿

<div class="flex flex-col gap-3">
  <span class="text-sm font-semibold text-gray-500" *ngIf="label">{{
    label
  }}</span>
  <div class="flex gap-4 select-none">
    <ng-content />
  </div>
</div>


// 컴포넌트 

import {
  AfterContentInit,
  Component,
  ContentChildren,
  Input,
  Optional,
  QueryList,
  Self,
} from '@angular/core';
import { NgControl } from '@angular/forms';
import { merge } from 'rxjs';
import { CustomValueAccessor } from '../custom-value-accessor';
import { RadioOptionComponent } from './radio-option/radio-option.component';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-radio',
  templateUrl: './radio.component.html',
  styleUrls: ['./radio.component.scss'],
  standalone: true,
  imports: [CommonModule],
})
export class RadioComponent
  extends CustomValueAccessor<string>
  implements AfterContentInit
{
  @ContentChildren(RadioOptionComponent)
  options!: QueryList<RadioOptionComponent>;
  @Input() label: string | undefined;
  constructor(@Self() @Optional() private ngControl: NgControl) {
    super();
    if (this.ngControl) this.ngControl.valueAccessor = this;
  }

  ngAfterContentInit(): void {
    merge(...this.options.map((option) => option.selected$)).subscribe({
      next: (value) => {
        this.writeValue(value);
      },
      complete: () => {
        const selectedOption = this.options.find(
          (option) => option.value === this.value
        );
        if (selectedOption) selectedOption.checked = true;
      },
    });
  }
}

1. input-radio 의 경우 여러개의 옵션이 필요하므로 옵션 영역과 범위 영역을 각각 컴포넌트화

 

 

 

/* 컴포넌트 활용 부분 */

// 템플릿

<app-radio label="권한 설정" formControlName="role">
      <app-radio-option
        *ngFor="let role of roles"
        [value]="role"
        name="role"
        [checked]="admin ? role === admin.role : false"
        >{{role}}</app-radio-option
      >
    </app-radio>


// 컴포넌트

adminForm = new FormGroup({
  role: new FormControl<Roles | null>(null, [Validators.required]),
});



console.log(this.adminForm.getRawValue().role!);

2. 컴포넌트를 가져와서 직접 사용하는 부분

반응형
LIST