web-dev-qa-db-fra.com

Manière courte d'attribuer la date à ngbDatepicker

J'utilise des formulaires réactifs dans mon Angular 2 webapp et je ne parviens pas à attribuer la date à ngbDatepicker (ngbootstrap 1 alpha 6). Mon objet a un objet de date tel que:

var myObject = {date: new Date(1, 9, 2016)};

et dans ma forme réactive, il est configuré comme suit:

input.form-control(name='date', ngbDatepicker, #date="ngbDatepicker", placeholder='jj.mm.aaaa', formControlName='date', type="text")

et je corrige le formulaire comme ceci:

this.form.patchValue({myObject: myObject});

Le problème est que ngbDatepicker prend la date avec la structure suivante:

{day: DD, month: MM, year: YYYY}

J'ai trouvé une solution de contournement qui:

this.form.controls.myObject.controls.date.valueChanges
        .map((value) => {
            if(value) {
                if (typeof value.getMonth === 'function') {
                    this.form.controls.myObject.patchValue({
                        date: {
                            day: value.getUTCDay(),
                            month: value.getUTCMonth(),
                            year: value.getUTCFullYear()
                        }
                    });
                }
            }
            return value;
        })
        .subscribe((value) => {

        });

Et tout fonctionne comme prévu (la date est mise à jour à chaque fois que le formulaire est corrigé), mais il est beaucoup trop détaillé (18 lignes de code) et mon formulaire comporte une douzaine de dates!

Ma question est la suivante: puis-je obtenir le même résultat avec une solution beaucoup plus courte?

8
ncohen

@ncohen, nous aussi, nous soulignons la douleur, voir: https://github.com/ng-bootstrap/ng-bootstrap/issues/754 . Il n'y a pas de solution parfaite pour le moment et il faut en fin de compte provenir de Angular lui-même sous forme d'analyseurs/formateurs connus de AngularJS. Il y a déjà 2 problèmes dans le référentiel Angular qui suivent votre cas d'utilisation en tant que demande de fonctionnalité: 

Je pense que pour le moment, votre meilleure option est d’extraire du code détaillé vers une fonction d’utilitaire et de l’appeler lorsque la conversion est nécessaire (comme suggéré dans l’un des commentaires).

2

Je ne sais pas si cela pourrait vous aider

ng-bootstrap: 1
angular: 2
bootstrap: 4

ngOnInit() {
const now = new Date();
const since = moment().subtract(14,'d').toDate();

this.model.fechaHasta = {year: now.getFullYear(), month: now.getMonth() + 1, day: now.getDate()};
this.model.fechaDesde = {year: since.getFullYear(), month: since.getMonth() + 1, day: since.getDate()};
}

HTML

<div class="input-group">
    <input class="form-control" placeholder="yyyy-mm-dd"
                name="fechaHasta" [(ngModel)]="model.fechaHasta" ngbDatepicker #d10="ngbDatepicker">

    <div class="input-group-addon" (click)="d10.toggle()">
       <img src="../../shared/img/calendar-icon.png" style="width: 1.2rem; height: 1rem; cursor: pointer;"/>
    </div>
</div>
5
Leonardo Ampuero

Je viens de trouver votre question en cherchant une solution au même problème. Ce que j’ai fait est tiré de momentjs, une bibliothèque de manipulation de date/heure ( http://momentjs.com ), et je manipule les dates provenant de la base de données via momentjs avant de les corriger dans le formulaire et initialisation de ngbDatepicker.

this.START_DATE est la valeur de la base de données et se présente sous la forme d'une chaîne START_DATE : "2017-08-27"

var _savedStartDate = moment(this.START_DATE).toObject();

var _savedStartDateObject = {day:0,month:0,year:0};

    _savedStartDateObject.day = _savedStartDate.date;
    _savedStartDateObject.month = _savedStartDate.months;
    _savedStartDateObject.year = _savedStartDate.years;

this.form.patchValue({
  START_DATE: _savedStartDateObject
})

Ceci est plus détaillé que nécessaire, vous pouvez créer l'objet et attribuer les attributs sur une ligne, mais cela est beaucoup plus lisible.

Fondamentalement, créez un objet date moment en passant la date sous forme de chaîne à la fonction moment (), puis appelez la fonction toObject sur le résultat, ce qui vous donne un objet comme celui-ci: {years: 2017, months: 7, date: 27, hours: 0, minutes: 0, seconds: 0, milliseconds: 0}

Créez ensuite un objet vide au format ngbDatepicker veut le voir {day:0,month:0,year:0}, mappez les attributs appropriés de l'objet moment à l'objet ngbDatepicker, puis appelez this.formpatchValue et transmettez l'objet nouvellement créé avec le format approprié.

Les documents momentjs pertinents sont ici http://momentjs.com/docs/#/displaying/as-object/

1
Stephen R. Smith