Angular(2/4/5/6) Преобразование массива временных интервалов во временной диапазон

#angular #string #switch-statement

#angular #строка #оператор переключения

Вопрос:

Привет, спасибо за все ваши ответы! Вот мое обновленное решение, основанное на ваших входных данных. Спасибо!

 getTime(apptTime) {
   const fields = apptTime.split("-");
   const startingTime = this.formatTime( fields[0]);
   const endingTime = this.formatTime( fields[1]);

   return startingTime   " - "   endingTime;
}

formatTime(time) {
    if (time < 12) {
      return time === 0 ? "12am" : time   "am";
    } else {
      return time === 12 ? time   "pm" : time - 12   "pm";
    }
  }
  

У меня есть string array => app_timeslots = [«09-12», «12-15», «15-18», «18-21»]
Который извлекается из серверной части, и я хотел бы отобразить его в виде переключателей следующим образом:

введите описание изображения здесь

appt.component.html

 <ng-container *ngFor="let appt of appt_timeslots" [ngSwitch]="appt">
   <label ngbButtonLabel class="btn btn-secondary active btn-radio btn-color">
      <input ngbButton type="radio" name="timeslot" value="{{ appt }}"/>
         <span *ngSwitchCase="'09-12'">9am - 12pm</span>
         <span *ngSwitchCase="'12-15'">12pm - 5pm</span>
         <span *ngSwitchCase="'15-18'">3pm - 6pm</span>
         <span *ngSwitchCase="'18-21'">6pm - 9pm</span>
   </label>
</ng-container>
  

Есть ли лучший способ получить мои временные интервалы, чтобы я мог отображать am / pm и тире вместо использования switch case?
Чтобы он мог обслуживать и другие временные интервалы (например, 2pm — 4pm), и мне не нужно вручную добавлять другой переключатель для обслуживания нового.
Ценю вашу помощь!

Комментарии:

1. Возможно, вместо этого в отображение времени в typescript. Создайте словарь с ключами = appt_timeslots значениями и значениями = строками с 9 утра до 12 вечера. например. {"09-12":"9am - 12pm", ...} . затем вы можете просто выполнить {{dict[appt]}}

2. За то время, которое у меня есть сейчас, я смог сделать вот так stackblitz.com/edit/angular-ngmodel-form-8hyfqc , пожалуйста, расширьте этот в соответствии с вашими требованиями, если это вам поможет..

Ответ №1:

Вот возможный подход.

Сначала я сохраняю внутренние данные как есть.

Затем я создам объект с исходными данными в качестве значения и отображаемым текстом на основе значения. Например, для элемента внутреннего массива '09-12' я создаю объект {value:'09-12', text: '9am-12pm'}

Ваш ts-файл:

  backendData =  ["09-12", "12-15", "15-18", "18-21"] //Data from the backend
 appt_timeslots = []  //This will be our object

 //I do the rest in ngOnInit but that's just for the example.
 ngOnInit() { 

    this.backendData.forEach(e => {
      var text = this.getTextFromValue(e);
      this.appt_timeslots.push({value: e, text: text});
    })
    console.log(this.appt_timeslots);
  }

 getTextFromValue(value:string){

    var timeSlots = value.split("-");
      var formattedTime = timeSlots.map(time => {
        time = this.setAMorPM(time);
        return time
      });

      var result = formattedTime.join("-")
      return result
  }

  setAMorPM(number: string){

    if(parseInt(number) > 12)
      number = (parseInt(number) - 12).toString()   'pm';
    else
      if(parseInt(number) == 0)
        number = "12am"
      else  
        if(number[0]=='0')
        {
          number = number.slice(1);
          number  = 'am';
        }

    return number
  }
  

Мы создаем объект на основе внутренних данных каждого элемента и помещаем его в массив object ( appt_timeslots ).

Две функции getTextFromValue() и toAMorPM() служат только для создания текста на основе значения, я разделил их для удобства чтения.

Ваш HTML-файл:

Теперь вам просто нужно выполнить цикл по вашему массиву объектов и при необходимости интерполировать значение или текст, вот так:

 <ng-container *ngFor="let appt of appt_timeslots" [ngSwitch]="appt.value">
  <label ngbButtonLabel class="btn btn-secondary active btn-radio btn-color">
     <input ngbButton type="radio" name="timeslot" value="{{ appt.value }}"/>
        <span *ngSwitchCase="appt.value">{{appt.text}}</span>
  </label>
</ng-container>
  

Примечание: Функции, вероятно, могут быть написаны более лаконично, но я думаю, что подход имеет смысл.

Ответ №2:

Мне нравится использовать канал для преобразования, у этого нет проверки формата, но он будет работать для вас

     import { Pipe, PipeTransform } from '@angular/core';

    @Pipe({
      name: 'timeslot'
    })
    export class TimeslotPipe implements PipeTransform {

      transform(value: string): any {
        const times = value.split('-');
        return `${this.generateTimeString(times[0])} - ${this.generateTimeString(times[1])}`;
      }

      private generateTimeString(hourValue: string): string {
        const suffix =  hourValue - 12 > -1 ? 'pm' : 'am';
        const twelveFormat =  hourValue - (suffix === 'pm' ? 12 : 0);
        return `${twelveFormat}${suffix}`;
      }
    }
  

и .html

 <p *ngFor="let slot of timeslots">{{slot | timeslot}}</p>