본문으로 건너뛰기

Angular와의 통합

DHTMLX Booking은 위젯 생성자를 감싸는 커스텀 컴포넌트를 통해 Angular와 통합됩니다. 이 가이드는 새 Angular 프로젝트를 생성하고, Booking을 설치하고, 데이터와 events를 포함한 위젯을 렌더링하는 과정을 안내합니다. 전체 참조 구현은 GitHub의 Angular 예제를 참조하십시오.

팁

이 가이드는 Angular 핵심 개념에 대한 기본 지식이 있다고 가정합니다. 소개가 필요하다면 Angular 문서를 참조하십시오.

프로젝트 생성​

Booking 통합을 추가하기 전에 Angular CLI로 새 Angular 앱을 생성합니다.

정보

시작하기 전에 Angular CLI와 Node.js를 설치하십시오.

다음 명령어는 새 my-angular-booking-app 프로젝트를 생성합니다:

ng new my-angular-booking-app
노트

CLI가 묻는 경우 Server-Side Rendering (SSR)과 Static Site Generation (SSG/Prerendering)을 비활성화하십시오. Booking 위젯은 클라이언트 측에서 DOM에 마운트됩니다.

명령어가 모든 필요한 도구를 설치합니다. 추가 명령어는 필요하지 않습니다.

의존성 설치​

프로젝트 디렉터리로 이동합니다.

다음 명령어는 새로 생성된 앱 폴더를 엽니다:

cd my-angular-booking-app

패키지 매니저로 의존성을 설치하고 개발 서버를 시작합니다.

다음 명령어는 yarn을 사용합니다:

yarn
yarn start

다음 명령어는 npm을 사용합니다:

npm install
npm start

앱은 예를 들어 http://localhost:4200과 같은 로컬호스트에서 실행됩니다.

앱에 Booking 추가​

Booking 패키지를 설치하기 전에 개발 서버를 중지하고, 위젯을 감싸는 Angular 컴포넌트를 생성합니다.

1단계. 패키지 설치​

Booking 평가판 패키지를 다운로드하고 패키지 README의 단계를 따르십시오. 평가판은 30일간 활성화됩니다.

2단계. Booking 컴포넌트 생성​

src/app/ 디렉터리에 booking 폴더를 생성하고 그 안에 booking.component.ts 파일을 추가합니다. 아래 단계를 완료하여 위젯을 연결합니다.

소스 파일 가져오기​

배포판에 맞는 경로를 사용하여 Booking 클래스를 가져옵니다:

  • dhx-booking-package — 로컬 폴더에서 설치한 PRO 버전
  • @dhx/trial-booking — 평가판

다음 코드 스니펫은 PRO 패키지에서 Booking을 가져옵니다:

import { Booking } from 'dhx-booking-package';

다음 코드 스니펫은 평가판 패키지에서 Booking을 가져옵니다:

import { Booking } from '@dhx/trial-booking';
정보

이 튜토리얼은 Booking 평가판을 사용합니다.

컨테이너 설정 및 Booking 초기화​

컴포넌트 템플릿에 호스트 컨테이너를 정의하고 ngOnInit()에서 Booking을 인스턴스화합니다. Angular가 컴포넌트를 제거할 때 위젯을 언마운트하려면 ngOnDestroy()에서 destructor()를 호출합니다.

다음 코드 스니펫은 컨테이너 엘리먼트와 라이프사이클 훅이 있는 Booking 컴포넌트를 선언합니다:

booking.component.ts
import { Booking } from '@dhx/trial-booking';
import { Component, ElementRef, OnInit, ViewChild, OnDestroy, ViewEncapsulation } from '@angular/core';

@Component({
encapsulation: ViewEncapsulation.None,
selector: "booking", // app.component.ts에서 <booking />으로 사용됨
styleUrls: ["./booking.component.css"],
template: `<div #container className="widget"></div>`,
})

export class BookingComponent implements OnInit, OnDestroy {
// Booking의 호스트 컨테이너
@ViewChild('container', { static: true }) booking_container!: ElementRef;

private _booking!: Booking;

ngOnInit() {
// Booking 인스턴스 생성
this._booking = new Booking(this.booking_container.nativeElement, {});
}

ngOnDestroy(): void {
this._booking.destructor(); // Booking 언마운트
}
}

스타일 추가​

Booking은 위젯 스타일시트와 크기가 지정된 컨테이너가 모두 필요합니다.

src/app/booking/ 디렉터리에 booking.component.css 파일을 생성합니다.

다음 코드 스니펫은 Booking 스타일시트를 가져오고 페이지와 위젯 컨테이너의 전체 높이를 설정합니다:

booking.component.css
/* Booking 스타일 가져오기 */
@import "@dhx/trial-booking/dist/booking.css";

/* 페이지 스타일 */
html,
body {
margin: 0;
padding: 0;
height: 100%;
}

/* Booking 컨테이너 */
.widget {
height: 100%;
}

데이터 로드​

Booking에 카드 데이터를 로드하려면 data 속성에 맞는 데이터셋을 준비합니다. 전체 데이터 형식과 로딩 시나리오는 데이터 로딩 가이드를 참조하십시오.

src/app/booking/ 디렉터리에 data.ts 파일을 생성합니다.

다음 코드 스니펫은 샘플 데이터셋을 반환하는 getData() 헬퍼를 정의합니다:

data.ts
export function getData() : any {
function getDate(addDays : any, hoursValue = 0, minutesValue = 0) {
const date = new Date();
const secondsValue = 0; // 분 단위로 반올림
const msValue = 0;

date.setDate(date.getDate() + addDays);
date.setHours(hoursValue, minutesValue, secondsValue, msValue);

return date.getTime();
}

return [
{
id: "ee828b5d-a034-420c-889b-978840015d6a",
title: "Natalie Tyson",
category: "Therapist",
subtitle: "2 years of experience",
details: "Cleveland Clinic\n9500 Euclid Ave",
preview: "https://snippet.dhtmlx.com/codebase/data/booking/01/img/01.jpg",
price: "$35",
review: {
stars: 4,
count: 120
},
slots: [
{
from: 9,
to: 20,
days: [1, 2, 3, 4, 5]
},
{
from: 10,
to: 18,
days: [6, 0]
}
]
},
{
id: "9b037564-77be-429f-b719-eebbe499027a",
title: "Emma Johnson",
category: "Cardiologist",
subtitle: "2 years of experience",
details: "Stanford Health Care\n1468 Madison Ave",
preview: "https://snippet.dhtmlx.com/codebase/data/booking/01/img/03.jpg",
price: "$25",
review: {
stars: 5,
count: 10
},
slots: [
{
from: 14,
to: 17,
size: 30,
gap: 10
},
{
from: 12,
to: 19,
size: 50,
gap: 20,
days: [2],
dates: [getDate(0)]
},
{
from: "18:30",
to: 20,
size: 20,
gap: 20,
days: [3, 4, 5]
},
],
usedSlots: [getDate(0, 12), getDate(0, 18)]
},
// ...
];
}

booking.component.ts를 열고 데이터셋을 가져온 후 ngOnInit() 내부의 Booking 구성에 전달합니다.

다음 코드 스니펫은 getData()를 Booking 생성자에 연결합니다:

booking.component.ts
import { Booking } from '@dhx/trial-booking';
import { getData } from "./data"; // 데이터 가져오기
import { Component, ElementRef, OnInit, ViewChild, OnDestroy, ViewEncapsulation } from '@angular/core';

@Component({
encapsulation: ViewEncapsulation.None,
selector: "booking",
styleUrls: ["./booking.component.css"],
template: `<div #container className="widget"></div>`,
})

export class BookingComponent implements OnInit, OnDestroy {
@ViewChild('container', { static: true }) booking_container!: ElementRef;

private _booking!: Booking;

ngOnInit() {
const data = getData(); // 데이터셋 로드
this._booking = new Booking(this.booking_container.nativeElement, {
data
});
}

ngOnDestroy(): void {
this._booking.destructor();
}
}

Booking 컴포넌트가 이제 로드된 데이터와 함께 렌더링됩니다. 위젯을 추가로 커스터마이징하려면 추가 구성 속성을 전달하십시오. 전체 목록은 속성 개요를 참조하십시오.

Events 처리​

위젯에서 사용자가 작업을 수행하면 event가 발생합니다. booking.api.on(eventName, handler)으로 event를 구독하여 작업에 반응합니다. 전체 events 목록은 Events 개요를 참조하십시오.

booking.component.ts를 열고 ngOnInit()에 event 구독을 추가합니다.

다음 코드 스니펫은 사용자가 슬롯을 선택할 때 슬롯 ID를 로그에 기록합니다:

booking.component.ts
// ...
ngOnInit() {
this._booking = new Booking(this.booking_container.nativeElement, {
start: new Date(2024, 5, 10),
});

// 선택된 슬롯 id 로그 출력
this._booking.api.on("select-slot", (obj) => {
console.log(obj.id);
});
}

ngOnDestroy(): void {
this._booking.destructor();
}

3단계. 앱에 Booking 등록​

애플리케이션 부트스트랩에 BookingComponent를 추가합니다. src/app/app.component.ts를 열고 기본 코드를 교체합니다.

다음 코드 스니펫은 AppComponent 내부에 Booking 컴포넌트를 렌더링합니다:

app.component.ts
import { Component } from "@angular/core";

@Component({
selector: "app-root",
template: `<booking/>` // booking.component.ts에 정의된 템플릿
})
export class AppComponent {
name = "";
}

*src/app/*에 app.module.ts를 생성하고 두 컴포넌트를 선언합니다.

다음 코드 스니펫은 루트 모듈에 AppComponent와 BookingComponent를 등록합니다:

app.module.ts
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";

import { AppComponent } from "./app.component";
import { BookingComponent } from "./booking/booking.component";

@NgModule({
declarations: [AppComponent, BookingComponent],
imports: [BrowserModule],
bootstrap: [AppComponent]
})
export class AppModule {}

src/main.ts를 열고 루트 모듈을 부트스트랩합니다.

다음 코드 스니펫은 AppModule로 애플리케이션을 시작합니다:

main.ts
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { AppModule } from "./app/app.module";
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.error(err));

앱을 시작하면 페이지에 데이터가 로드된 Booking을 볼 수 있습니다.

Angular 애플리케이션에서 데이터가 로드된 DHTMLX Booking 위젯

프로젝트 요구 사항에 맞게 코드를 커스터마이징하십시오. 전체 참조 구현은 GitHub에서 확인할 수 있습니다.