NgBootstrap / NgbDatepicker с пользовательским шаблоном dayTemplate - PullRequest
0 голосов
/ 18 марта 2019

У меня есть страница с NgbDatepicker с пользовательским шаблоном dayTemplate для настройки стилей и отображения некоторой другой информации о каждом дне:

enter image description here

Это выглядит довольнохорошо, но это очень медленно , через несколько минут страница начинает зависать!

Я довольно новичок в Angular 7 и NgBootstrap, вот что я могу сделать, чтобы улучшить производительностьcomponent?

Похоже, что NgbDatepicker перерисовывает все после каждой итерации с помощью средства выбора даты, также наведите курсор мыши.Это поведение можно отключить?

Вы можете проверить демонстрацию на stackblitz , чтобы увидеть, о чем я говорю.Я не знаю почему, но локально в 10 раз медленнее (также работает режим производства скомпилированной версии).Я поставил console.log(calendarColor[0]); в строке 110, чтобы показать итерацию, о которой я говорю, и с этой строкой она немного медленнее.Кроме того, инструменты de Chrome Dev закрывали страницу после нескольких минут на странице.

КОМПОНЕНТ:

  formatDate(date: NgbDate): string {
    const month = `0${date.month}`.slice(-2);
    const day = `0${date.day}`.slice(-2);
    return `${date.year}-${month}-${day}`;
  }

  getDayCalendarColor(date: NgbDate): CalendarColor {
    const calendarColor = this.calendarColors.filter(cC => {
      return cC.date === this.formatDate(date);
    });
    if (!calendarColor.length) {
      return;
    }
    console.log(calendarColor[0]);
    return calendarColor[0];
  }

  cssCustomDay(date: NgbDate): string {
    const cssApartmentSeasonType = this.cssApartmentSeasonType(date);
    const cssCalendarType = this.cssCalendarType(date);
    return cssApartmentSeasonType + ' ' + cssCalendarType;
  }

  cssApartmentSeasonType(date: NgbDate): string {
    const calendarColor = this.getDayCalendarColor(date);
    if (!calendarColor || !ApartmentSeasonType[calendarColor.apartmentSeasonType]) {
      return;
    }
    return ApartmentSeasonType[calendarColor.apartmentSeasonType];
  }

  cssCalendarType(date: NgbDate): string {
    const calendarColor = this.getDayCalendarColor(date);
    if (!calendarColor || !CalendarType[calendarColor.calendarType]) {
      return;
    }
    const cssClass = `${CalendarType[calendarColor.calendarType]}${CalendarDay[calendarColor.calendarDay]}`;
    const isoDateString = this.formatDate(date);

    if (!this.dayCssClasses[isoDateString]) {
      this.dayCssClasses[isoDateString] = '';
    }
    if (
      !this.dayCssClasses[isoDateString] ||
      (this.dayCssClasses[isoDateString] && !this.dayCssClasses[isoDateString].includes(cssClass))
    ) {
      this.dayCssClasses[isoDateString] += cssClass;
    }
    return this.dayCssClasses[isoDateString];
  }

  dayDescription(date: NgbDate): string {
    const calendarColor = this.getDayCalendarColor(date);
    if (!calendarColor) {
      return '';
    }

    let description = 'Available ';

    let price = calendarColor.apartmentSeasonPrice;

    if (
      CalendarType[calendarColor.calendarType] &&
      [CalendarType.reserved, CalendarType.reservedOwner].includes(calendarColor.calendarType) &&
      [CalendarDay.First, CalendarDay.Center].includes(calendarColor.calendarDay)
    ) {
      return `\n ${CalendarTypeLabel.get(calendarColor.calendarType)}`;
    }

    if (calendarColor.calendarDiscountPercentage) {
      price = price - (price * calendarColor.calendarDiscountPercentage) / 100;
    }

    if (ApartmentSeasonType[calendarColor.apartmentSeasonType]) {
      description +=
        `${ApartmentSeasonTypeLabel.get(calendarColor.apartmentSeasonType)} ` +
        `${this.currencyPipe.transform(price, 'EUR')}`;
    }

    if (
      CalendarType[calendarColor.calendarType] &&
      [CalendarDay.First, CalendarDay.Center].includes(calendarColor.calendarDay)
    ) {
      description += `\n ${CalendarTypeLabel.get(calendarColor.calendarType)}`;
      if (calendarColor.calendarDiscountPercentage) {
        description += ` ${calendarColor.calendarDiscountPercentage}%`;
      }
    }

    return description;
  }  

ШАБЛОН:

<ngb-datepicker
  displayMonths="2"
  navigation="arrows"
  [dayTemplate]="dayTemplate"
  [showWeekNumbers]="true"
  outsideDays="hidden"
>
</ngb-datepicker>

<ng-template #dayTemplate let-date>
  <span class="custom-day" [ngClass]="cssCustomDay(date)" [ngbTooltip]="dayDescription(date)">
    <span>
      {{ date.day }}
    </span>
  </span>
</ng-template>

1 Ответ

0 голосов
/ 19 марта 2019

Чтобы улучшить ваш код (я не знаю, является ли улучшение большим улучшением):

getDayCalendarColor(date: NgbDate): CalendarColor {
    //use an auxiliar variable
    const dateSearch=this.formatDate(date);
    //use "find", not filter -return undefined if not found-
    return this.calendarColors.find(cC => cC.date ===dateSearch);
  }

Вы также можете фильтровать календариЦвета при изменении месяца и года календаря

Другое дело - не использовать ngToolTip каждый день или использовать контекст и ручное управление тигром с помощью (наведения мыши) и (наведения мыши) - я не уверен в этом последнем варианте -

...