Formato di conversione da data predefinito a JSON nell'app Angular

Nov 30 2020

Supponiamo che un componente (all'interno dell'app angolare) abbia diverse forme reattive contenenti datepicker (sto usando mat-datepickerda materiale angolare lib) e altri input. Dopo che un utente ha premuto il pulsante "Invia", invio il valore dei moduli a supportato (con HttpClient.post). Il problema è che i campi del datepicker sono serializzati come "2020-11-18T22:00:00.000Z"(ovviamente Date.toJSON()viene chiamato il metodo) mentre il backend si aspetta un altro formato.

Nota che sto usando formlylib per costruire i miei moduli, perché l'insieme di componenti su ogni modulo può variare. Potresti non avere familiarità, formlyma comunque anche l'insieme di datepicker può variare, quindi non posso convertire direttamente i campi del datepicker perché non conosco l'elenco esatto dei campi della data in un luogo in cui invio il valore dei moduli.

C'è una soluzione elegante al mio problema? Non riesci a pensare a qualcosa di meglio del patching scimmia Date.prototype.toJSON()o del ciclo attraverso gli oggetti inviati sul server, controlla il tipo di campi e cambia campo se è un Date? Non riesco a trovare un modo per impostare il formato dell'output del valore da datepicker sia in material che in formly.

Risposte

1 ibenjelloun Dec 04 2020 at 15:23

L'implementazione di ControlValueAccessor sarebbe una soluzione elegante. L'idea è di creare un componente di selezione della data che prenda il formato della data come input e restituisca il formato come output.

Per questo devi solo creare un nuovo componente che chiamerei MatDatepickerWrapperComponentper questo esempio. Il modello di questo componente non sarebbe altro che il selettore della data del materiale:

<mat-form-field appearance="fill">
  <mat-label>Choose a date</mat-label>
  <input matInput [matDatepicker]="picker" [(ngModel)]="model" (ngModelChange)="modelChange($event)">
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

Dal lato dei componenti, dovrai implementare ControlValueAccessor e fare le trasformazioni necessarie:

writeValue(value: string): void {
    this.model = transformDateFromMyFormatToIso(value);
}
modelChange(value: string) {
    const transformedValue = transformIsoDateToMyFormat(value);
    this.onChange(transformedValue);
  }

Ora puoi aggiungere il nuovo componente a un modulo nel modo in cui avresti aggiunto quello originale.

Ecco un esempio di stackblitz in esecuzione.

1 RobinDijkhof Dec 04 2020 at 05:26

Proverei a usare un intercettore HTTP. Penso che potresti essere in grado di utilizzare il tuo intercettore per cambiare tutte le date nel corpo in qualcos'altro.

inserire la descrizione del collegamento ecco un esempio di come funziona l'interceptor. Nell'esempio viene aggiunta un'intestazione. Qui e qui ci sono un esempio di modifica del corpo.

1 Becike Dec 04 2020 at 15:03

Ho avuto lo stesso problema. Potrei risolvere questo problema sovrascrivendo il convertitore di date JSON nel componente dell'app .:

overrideToJSONDate() {
    Date.prototype.toJSON = function () {
      return new Date(this).toLocaleString();
    }
  }

Chiamo questa funzione una volta nel costruttore del componente dell'app. Puoi applicare e logica all'interno della funzione ma assicurati di tornare con la stringa corrente.