박주니 개발 정리

angular calendar 공용 모듈 생성 및 사용 본문

angular

angular calendar 공용 모듈 생성 및 사용

박주니 2023. 8. 4. 20:10
728x90
반응형

설명 이유) 프론트를 react로 진행하다가 이번에 신규 프로젝트는 angular로 진행하게 되어서 정리하게 되었습니다.
 
angular 환경설정은 다 되어있다는 조건으로 진행하겠습니다. 
 
1. terminal에서 npm install -g @angular/cli 진행합니다. 

  • 설명) angular/cli를 이용해서 component를 쉽게 연결하고 설정하기 위함입니다. 

2. 메인으로 진행할 container를 생성합니다. terminal에서 ng generate component container을 진행합니다. 

  • 설명) container은 예를 들어서 메인페이지라고 했을 때 다른 component들을 bind해서 사용하기 위함입니다. 

3. calendar module로 이용하기 위해 terminal에서 ng generate component calendar을 진행합니다. 

  • 설명) 단순하게 말하면 calendar 자체 모든 기능들을 만들고 container에 적용하기 위함입니다. 

4. app.module.ts에서 제대로 calender component가 import가 되었는 지 확인합니다. 

  • 설명)
    1. 현재 app 폴더안에 component와 calendar폴더가 존재함으로 공용 모듈 관리는 app.module.ts에서 진행합니다. 여기에 설정을 하게되면 별도 페이지 import하지 않아도 해당 module이 기능이 정상적으로 작동될 시 문제 없이 진행이 가능합니다. react에서 App.js와 비슷한 역할이라고 보시면 됩니다.
    2. ng generate component 진행할 때부터 app.module.ts에 자동으로 import 셋팅이 됩니다. 

5. calendar중에서 bsDatepicker로 사용할 것이기 때문에 npm i ngx-bootstrp을 설치하고 imports에 연결합니다. 

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ContainerComponent } from './Container/container.component';
import { CalendarComponent } from './calendar/calendar.component';
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
@NgModule({
  declarations: [
    AppComponent,
    ContainerComponent,
    CalendarComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    FormsModule,
    BsDatepickerModule.forRoot(),
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

6. 추가적인 설정방법은 angular bootstrap 공식문서 통해서 연결하시면 됩니다. 

  • datepicker 부트스트랩 만드는 것을 설명하고자 하는것은 아니기 때문에 넘어가겠습니다. 
  • 공식문서가 중요한 이유) chatgpt 설명을 듣고 진행을 했을 때 달력 자체 기능이 안됬었는데 공식문서에서 animations 설정이 별도 추가하는 것을 확인이 되었고 문제를 해결할 수 있었습니다. 
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

https://valor-software.com/ngx-bootstrap/#/components/datepicker?tab=api 

Angular Bootstrap

valor-software.com

7. calendar.component.html을 기본 공식문서에 맞는 달력에 맞게 셋팅합니다. 

<input
  type="text"
  class="form-control datepicker"
  id="datepicker"
  placeholder=""
  bsDatepicker
  [bsConfig]="isStartDate ? startDateConfig : endDateConfig"
  [readonly]="isDatepickerDisabled"
  (keydown)="preventInput($event)"
  [(bsValue)]="isStartDate ? startDate : endDate"
  (bsValueChange)="setDate($event)"
/>

8. 달력 기본 기능이 될 수 있게  calender.component.ts 코드를 작성합니다. 

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

@Component({
  selector: 'app-calendar',
  templateUrl: './calendar.component.html',
  styleUrls: ['./calendar.component.css'],
})
export class CalendarComponent {
  public isDatepickerDisabled: boolean = true;

  @Input() startDate: Date = new Date();
  @Input() endDate: Date = new Date();
  @Input() isStartDate: boolean = true; // 입력 속성 추가
  @Input() endDateEditable: boolean = true; // 추가: endDate 수정 가능 여부 플래그
  @Output() startDateChange = new EventEmitter<Date>();
  @Output() endDateChange = new EventEmitter<Date>();

  ngOnInit() {
    // 현재 날짜를 구합니다.
    const currentDate = new Date();

    // 6개월 전 날짜를 구합니다.
    const sixMonthsAgo = new Date();
    sixMonthsAgo.setMonth(currentDate.getMonth() - 6);

    // 현재 날짜를 최대 날짜로 설정합니다.
    if (this.isStartDate) {
      this.startDate = sixMonthsAgo;
    }
    if (this.endDateEditable) {
      this.endDate = currentDate;
    }

    // 달력을 활성화합니다.
    this.isDatepickerDisabled = false;
  }

  public setDate(date: Date) {
    console.log(date)
    if (this.isStartDate) {
      this.startDate = date;
      this.startDateChange.emit(this.startDate); // 이벤트 발생 시 부모 컴포넌트로 startDate 변경을 알림
    } else {
      // 추가: endDate 수정 가능 여부 플래그에 따라 endDate를 설정합니다.
      if (this.endDateEditable) {
        this.endDate = date;
        this.endDateChange.emit(this.endDate); // 이벤트 발생 시 부모 컴포넌트로 endDate 변경을 알림
      }
    }
  }

  public preventInput(event: KeyboardEvent): void {
    event.preventDefault();
  }

  // startDate에 대한 설정
  public startDateConfig = {
    minDate: new Date(new Date().getFullYear(), new Date().getMonth() - 6, new Date().getDate()),
    maxDate: new Date(),
    dateInputFormat: 'YYYY-MM-DD',
    containerClass: 'theme-dark-blue',
  };

  // endDate에 대한 설정: 최대 날짜를 현재 날짜로 제한
  public endDateConfig = {
    minDate: new Date(new Date().getFullYear(), new Date().getMonth() - 6, new Date().getDate()),
    maxDate: new Date(),
    dateInputFormat: 'YYYY-MM-DD',
    containerClass: 'theme-dark-blue',
  };
}
  • 설명) 
    • @Input() - 추후에 해당 component를 bind를 진행할 때 <app-calendar [isStartDate]="true"></app-calendar>라고 했을 때 calendar.component.ts에서 @Input() isStartDate:boolean = true;  로 입력 속성값을 확인하고 기재한 값을 확인해서 조건문으로 사용할 수 있습니다. 
    • @Output() - 값을 emit으로 보내게 되면 (startDateChange) = "onStartDateChange($event)"로 되어있는 것을 확인하실 수 있는데 이건 부모 component에서 startDateChange에 emit으로 내보낸 값을 onStartDateChange 함수를 셋팅해서 가지고 올 수 있습니다. 
    • bsConfig - calendar 구성 폼을 셋팅할 때 사용합니다. 
    • bsValue - calendar 선택한 값
    • setDate - 이 함수는 bsValue에서 받은 값을 이용하고 emit으로 내보냅니다. 그럼 단방향으로 부모 component가 그 값을 사용 가능합니다. 

9. container.component.html에 해당 calendar component를 바인딩합니다.

<app-calendar
  [startDate]="startDate"
  [isStartDate]="true"
  [endDateEditable]="false"
></app-calendar>
<app-calendar
  [endDate]="endDate"
  [isStartDate]="false"
  [endDateEditable]="true"
></app-calendar>
  • 설명)
    • app-calendar 태그 의미 - calendar.component.ts에서 selector을 app-calendar로 설정했기 때문에 해당 태그를 사용하면 해당 ts와 설정된 templateUrl를 사용할 수 있습니다. 

 

728x90
반응형
Comments