Перед тем как смотреть пример из этого раздела рекомендуем изучить информацию в TS SDK про асинхронное выполнение (async/await).
Для начала добавим в наш виджет days_count асинхронные операции. Для расчёта рабочих часов будем использовать методы рабочего календаря:
Код:
async function onInit(): Promise<void> {
if (!Context.data.first_date) {
return;
}
if (!Context.data.second_date) {
return;
}
// Вычисляем календарные дни
const duration = Context.data.first_date.sub(Context.data.second_date);
if (duration) {
Context.data.days_count = Math.round(Math.abs(duration.days));
}
// Вычисляем рабочие часы
try {
// Обращаемся к рабочему календарю
const workTime = await System.productionSchedule.getWorkingTime(Context.data.first_date, Context.data.second_date);
Context.data.hours_count = workTime.hours;
}
catch (err) {
// Здесь нужно обработать ошибку
}
}
Также доработаем отображение. Сделаем так, чтобы панели с продолжительностью отпуска и пересечениями показывались, только когда пользователь заполняет хотя бы одну дату на форме:
Код:
<%if (Context.data.days_count || Context.data.hours_count) { %>
<div class="days_count">
<div>
<%= Context.data.first_date.format("DD.MM.YYYY") %> - <%= Context.data.second_date.format("DD.MM.YYYY")%>
(<%= Context.data.days_count%> дней, <%= Context.data.hours_count%> раб.часов)
</div>
</div>
<% } %>
Теперь в виджете учитываются выходные и праздничные дни, однако для этого отправляется запрос на сервер.
Форма с виджетом будет выглядеть следующим образом:
Попробуем ускорить отображение виджета. Для этого вынесем получение рабочих часов в отдельную функцию и будем вызывать её без await:
Код:
async function onInit(): Promise<void> {
if (!Context.data.first_date) {
return;
}
if (!Context.data.second_date) {
return;
}
// Вычисляем календарные дни
const duration = Context.data.first_date.sub(Context.data.second_date);
if (duration) {
Context.data.days_count = Math.round(Math.abs(duration.days));
}
calcWorkHours();
}
async function calcWorkHours(): Promise<void> {
// Вычисляем рабочие часы
try {
// Обращаемся к рабочему календарю
const workTime = await System.productionSchedule.getWorkingTime(Context.data.first_date!, Context.data.second_date!);
Context.data.hours_count = workTime.hours;
}
catch (err) {
// Здесь нужно обработать ошибку
}
}
В данном виджете различие в скорости почти незаметно. Попробуем сделать такую же операцию со вторым виджетом, vacation_overlap:
Код:
async function onInit(): Promise<void> {
if (!Context.data.first_date || !Context.data.second_date) {
return;
}
Server.rpc.getVacationOverlap();
}
На форме создания отпуска будет заметно, что сначала отобразится пустая панель Пересечения:
И только через какое-то время отобразится список отпусков:
Такой подход помогает выиграть время при открытии формы или виджета. Если загрузка данных занимает более 300 мс, выносите её в асинхронные функции и вызывайте без await.