Данное руководство предполагает, что вы обладаете базовыми знаниями концепций и паттернов Angular. Если это не так, рекомендуем ознакомиться с документацией Angular и пройти обучающий курс для начинающих.
DHTMLX Scheduler отлично работает с Angular. Практический пример можно найти на GitHub: DHTMLX Scheduler with Angular Demo.
Перед началом убедитесь, что у вас установлены Angular CLI и Node.js. Затем выполните команду:
ng new my-angular-scheduler-app
Эта команда подготовит все необходимые инструменты и зависимости, никаких дополнительных шагов не потребуется.
Далее перейдите в папку приложения:
cd my-angular-scheduler-app
Запустите приложение одной из следующих команд:
yarn start
или
npm start
Теперь приложение будет доступно по адресу http://localhost:4200.
Чтобы добавить DHTMLX Scheduler, сначала остановите запущенное приложение, нажав Ctrl+C в терминале. Затем установите пакет Scheduler.
PRO-версии библиотеки доступны через npm/yarn из нашего приватного репозитория. Следуйте этой инструкции, чтобы получить доступ.
После получения Evaluation-версии установите её с помощью:
npm install @dhx/trial-scheduler
yarn add @dhx/trial-scheduler
Также, поскольку zip-пакет библиотеки структурирован как модуль npm, вы можете установить его из локальной папки.
Создайте новый компонент для интеграции Scheduler. Внутри директории src/app/ создайте папку scheduler и добавьте в неё файлы: scheduler.component.ts, scheduler.component.css и scheduler.component.html.
В scheduler.component.html добавьте следующий шаблон для Scheduler:
scheduler/scheduler.component.html
<div #scheduler_here class="dhx_cal_container" style="width: 100%; height:100vh">
<div class="dhx_cal_navline">
<div class="dhx_cal_prev_button"></div>
<div class="dhx_cal_next_button"></div>
<div class="dhx_cal_today_button"></div>
<div class="dhx_cal_date"></div>
<div class="dhx_cal_tab" data-tab="day"></div>
<div class="dhx_cal_tab" data-tab="week"></div>
<div class="dhx_cal_tab" data-tab="month"></div>
</div>
<div class="dhx_cal_header"></div>
<div class="dhx_cal_data"></div>
</div>
Стили для Scheduler объявите отдельно в scheduler.component.css. Пример базовых стилей:
scheduler/scheduler.component.css
@import "@dhx/trial-scheduler/codebase/dhtmlxscheduler.css";
:host {
display: block;
position: relative;
height: 100%;
width: 100%;
}
Чтобы контейнер Scheduler занимал всю область body, добавьте эти стили в styles.css в папке src:
src/styles.css
html,
body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
Откройте scheduler.component.ts и scheduler.component.css для импорта исходных файлов Scheduler. В зависимости от способа установки:
scheduler.component.ts
import { Scheduler, SchedulerStatic } from 'dhtmlx-scheduler';
scheduler.component.css
@import "@dhtmlx-scheduler/codebase/dhtmlxscheduler.css";
scheduler.component.ts
import { Scheduler, SchedulerStatic } from '@dhx/trial-scheduler';
scheduler.component.css
@import "@dhx/trial-scheduler/codebase/dhtmlxscheduler.css";
В данном руководстве используется trial-версия.
Чтобы отобразить Scheduler на странице, необходимо указать контейнер для его рендера. Пример кода:
scheduler.component.ts
import { Scheduler, SchedulerStatic } from "@dhx/trial-scheduler";
import { Component, ElementRef, OnInit, OnDestroy,
ViewChild, ViewEncapsulation } from "@angular/core";
@Component({
encapsulation: ViewEncapsulation.None,
selector: "scheduler",
styleUrls: ["./scheduler.component.css"],
templateUrl: 'scheduler.component.html'
})
export class SchedulerComponent implements OnInit, OnDestroy {
@ViewChild("scheduler_here", { static: true }) schedulerContainer!: ElementRef;
private _scheduler?: SchedulerStatic;
ngOnInit() {
let scheduler = Scheduler.getSchedulerInstance();
scheduler.init(
this.schedulerContainer.nativeElement,
new Date(2024, 9, 7),
"week",
);
this._scheduler = scheduler;
}
ngOnDestroy() {
if (this._scheduler) this._scheduler.destructor();
}
}
Здесь хук жизненного цикла ngOnInit() инициализирует Scheduler, а ngOnDestroy() вызывает scheduler.destructor() для очистки при уничтожении компонента.
Далее замените содержимое по умолчанию на компонент Scheduler. Откройте src/app/app.component.ts и обновите его следующим образом:
src/app/app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `<scheduler></scheduler>`,
})
export class AppComponent {
name = '';
}
Создайте app.module.ts в src/app/ и подключите SchedulerComponent следующим образом:
src/app/app.module.ts
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { AppComponent } from "./app.component";
import { SchedulerComponent } from "./scheduler/scheduler.component";
@NgModule({
declarations: [AppComponent, SchedulerComponent],
imports: [BrowserModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
Наконец, обновите src/main.ts, заменив его содержимое на:
src/main.ts
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { AppModule } from "./app/app.module";
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
После повторного запуска приложения на странице появится пустой Scheduler.
Чтобы загрузка данных в Scheduler для Angular работала, необходимо добавить сервис для событий. Перед этим нужно определить модель события.
Для создания модели события используйте команду:
ng generate class models/event --skip-tests
В новом файле event.ts в папке models добавьте следующий код:
models/event.ts
export class Event {
id!: number;
start_date!: string;
end_date!: string;
text!: string;
}
Далее создайте сервис событий. Это класс, который отвечает за управление определёнными событиями. В Angular сервисы могут внедряться с помощью Dependency Injection. Они могут содержать данные, функции или функциональность, необходимую приложению. Здесь будет создан сервис данных для передачи событий Scheduler.
Для генерации сервиса выполните:
ng generate service services/event --flat --skip-tests
В новом файле event.service.ts в папке services добавьте следующий код:
services/event.service.ts
import { Injectable } from '@angular/core';
import { Event } from "../models/event";
@Injectable()
export class EventService {
get(): Promise<Event[]>{
return Promise.resolve([
{ id: 1, start_date: "2023-05-16 09:00", end_date: "2023-05-16 13:00",
text: "Event 1" },
{ id: 2, start_date: "2023-05-18 10:00", end_date: "2023-05-18 14:00",
text: "Event 2" },
]);
}
}
Декоратор @Injectable() помечает сервис как доступный для внедрения. В дальнейшем этот сервис будет внедрён в компонент.
В данный момент метод get() возвращает промис с жёстко заданными событиями. Также можно загружать данные с сервера и возвращать промис. Компонент Scheduler будет использовать EventService для получения событий. Для этого импортируйте EventService в scheduler.component.ts:
scheduler.component.ts
import {EventService} from "../services/event.service";
Затем укажите EventService как provider в декораторе @Component:
scheduler.component.ts
@Component({
encapsulation: ViewEncapsulation.None,
selector: "scheduler",
providers: [EventService],
styleUrls: ["./scheduler.component.css"],
templateUrl: 'scheduler.component.html'
})
Это гарантирует, что для каждого SchedulerComponent будет создан новый экземпляр сервиса. Для внедрения сервиса в компонент добавьте следующий конструктор в класс SchedulerComponent:
scheduler.component.ts
constructor(private eventService: EventService){}
Обновите метод ngOnInit() чтобы:
scheduler.component.ts
scheduler.config.date_format = "%Y-%m-%d %H:%i";
scheduler.init(this.schedulerContainer.nativeElement, new Date(2024, 9, 7));
this.eventService.get()
.then((data) => {
scheduler.parse(data);
});
Полный файл scheduler.component.ts будет выглядеть так:
scheduler.component.ts
import { Scheduler, SchedulerStatic } from "@dhx/trial-scheduler";
import { Component, ElementRef, OnInit, OnDestroy,
ViewChild, ViewEncapsulation } from "@angular/core";
import {EventService} from "../services/event.service";
@Component({
encapsulation: ViewEncapsulation.None,
selector: "scheduler",
providers: [EventService],
styleUrls: ['scheduler.component.css'],
templateUrl: 'scheduler.component.html'
})
export class SchedulerComponent implements OnInit, OnDestroy {
@ViewChild("scheduler_here", { static: true }) schedulerContainer!: ElementRef;
private _scheduler?: SchedulerStatic;
constructor(private eventService: EventService) { }
ngOnInit() {
let scheduler = Scheduler.getSchedulerInstance();
scheduler.config.date_format = "%Y-%m-%d %H:%i";
scheduler.init(
this.schedulerContainer.nativeElement,
new Date(2024, 9, 7),
"week",
);
this.eventService.get().then((data) => {scheduler.parse(data);});
this._scheduler = scheduler;
}
ngOnDestroy() {
if (this._scheduler) this._scheduler.destructor();
}
}
После перезагрузки страницы приложения Scheduler отобразит события.
Для отслеживания изменений, внесённых в Gantt, можно использовать обработчик dataProcessor для взаимодействия с серверной частью. Этот обработчик может быть определён как функция или объект router. dhtmlxScheduler поддерживает ответы от обработчика в виде Promise, что обеспечивает корректную обработку действий.
DataProcessor можно создать с помощью метода API createDataProcessor() для отслеживания изменений следующим образом:
scheduler.createDataProcessor(function(entity, action, data, id) {
scheduler.message(`${entity} ${action}`);
});
Если сервис изменяет идентификатор события после создания новой записи (что является распространённой практикой), Promise должен возвращать объект, содержащий {id: databaseId} или {tid: databaseId}. Это позволяет Scheduler обновить запись с новым идентификатором из базы данных.
Подробнее об интеграции с серверной частью читайте здесь.
Теперь Angular Scheduler настроен. Вы можете посмотреть полный демо-проект на GitHub.
Обратите внимание, что сам Scheduler не обеспечивает защиту от угроз, таких как SQL-инъекции, XSS или CSRF-атаки. Обеспечение безопасности приложения лежит на ответственности backend-разработчиков.
Больше информации о возможных уязвимостях и рекомендуемых мерах безопасности вы найдёте в статье Application Security.
Наверх