无法使用 angular 表单将日期绑定到 angular material 2 日期选择器
Can not bind date to angular material 2 date picker using angular forms
我正在尝试将 angular material 2 日期选择器与 angular 表单一起使用,但出现此错误:
vendor.bundle.js:92803 ERROR TypeError: Cannot read property 'invalid' of undefined
at MdInput.defaultErrorStateMatcher [as errorStateMatcher] (vendor.bundle.js:121344)
at MdInput.webpackJsonp.../../../material/@angular/material.es5.js.MdInput._updateErrorState (vendor.bundle.js:131778)
at MdInput.webpackJsonp.../../../material/@angular/material.es5.js.MdInput.ngDoCheck (vendor.bundle.js:131739)
at checkAndUpdateDirectiveInline (vendor.bundle.js:102634)
at checkAndUpdateNodeInline (vendor.bundle.js:104132)
at checkAndUpdateNode (vendor.bundle.js:104071)
at prodCheckAndUpdateNode (vendor.bundle.js:104765)
at Object.View_FormComponent_0._co [as updateDirectives] (ng:///AppModule/FormComponent.ngfactory.js:2337)
at Object.updateDirectives (vendor.bundle.js:104522)
at checkAndUpdateView (vendor.bundle.js:104038)
下面是我的组件的代码:
import {Component, OnInit, Output, Input, EventEmitter} from "@angular/core";
import {FormControl, Validators, FormGroup} from "@angular/forms";
import {ReferentialService} from "../shared/referential.service";
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit {
private form: FormGroup;
@Input() model: any;
isValidationMode: boolean;
@Output('cancel') cancel$: EventEmitter<any>;
@Output('submit') submit$: EventEmitter<any>;
// select lists
languages: any;
types: any;
subtypes: any;
entities: any;
managements: any;
countries: any;
services: any;
constructor(private _referentialService: ReferentialService) {
this.submit$ = new EventEmitter();
this.cancel$ = new EventEmitter();
this.model = {};
this.form = this._buildForm();
}
ngOnInit() {
this.initSelectLists();
}
/**
* Function to handle component update
*
* @param record
*/
ngOnChanges(record) {
if (record.model && record.model.currentValue) {
this.model = record.model.currentValue;
this.isValidationMode = !!this.model;
this.form.patchValue(this.model);
}
}
/**
* Function to init select list
*/
initSelectLists() {
this._referentialService.getCountries().subscribe((countries: any[]) => this.countries = countries);
this._referentialService.getLanguages().subscribe((languages: any[]) => this.languages = languages);
this._referentialService.getTypes().subscribe((types: any[]) => this.types = types);
this._referentialService.getSubTypes().subscribe((subtypes: any[]) => this.subtypes = subtypes);
this._referentialService.getEntities().subscribe((entities: any[]) => this.entities = entities);
this._referentialService.getServices().subscribe((services: any[]) => this.services = services);
this._referentialService.getManagements().subscribe((managements: any[]) => this.managements = managements);
}
/**
* Function to emit event to cancel process
*/
cancel() {
this.cancel$.emit();
}
/**
* Function to emit event to submit form and person
*/
submit(doc: any) {
this.submit$.emit(doc);
}
/**
* Function to build our form
*
* @returns {FormGroup}
*
* @private
*/
private _buildForm(): FormGroup {
return new FormGroup({
file: new FormControl('', Validators.compose([])),
documentid: new FormControl('', Validators.compose([Validators.required])),
title: new FormControl('', Validators.compose([Validators.required])),
name: new FormControl('', Validators.compose([Validators.required])),
format: new FormControl('', Validators.compose([Validators.required])),
summary: new FormControl('', Validators.compose([Validators.required])),
mnesysid: new FormControl('', Validators.compose([Validators.required])),
entity: new FormControl('', Validators.compose([Validators.required])),
management: new FormControl('', Validators.compose([])),
service: new FormControl('', Validators.compose([])),
creationDate: new FormControl(null, Validators.compose([])),
sendDate: new FormControl({
value: this.model.creationDate
}, Validators.compose([Validators.required])),
type: new FormControl('', Validators.compose([Validators.required])),
subtype: new FormControl('', Validators.compose([])),
archivist: new FormControl({
value: this.model.archivist,
disabled: true
}, Validators.compose([Validators.required])),
firstname: new FormControl({value: this.model.name, disabled: true}, Validators.compose([Validators.required])),
lastname: new FormControl({
value: this.model.firstname,
disabled: true
}, Validators.compose([Validators.required])),
beneficiary: new FormControl('', Validators.compose([])),
depositid: new FormControl('', Validators.compose([])),
filepath: new FormControl('', Validators.compose([])),
isprivate: new FormControl('', Validators.compose([])),
language: new FormControl('', Validators.compose([Validators.required])),
country: new FormControl('', Validators.compose([])),
publicyear: new FormControl(null, Validators.compose([])),
version: new FormControl('', Validators.compose([])),
status: new FormControl('', Validators.compose([])),
comment: new FormControl('', Validators.compose([Validators.required]))
});
}
}
这是我的 html 代码
<md-card>
<md-card-title>
<span *ngIf="isValidationMode" style="color: #00965E !important;">Validation du document</span>
<span *ngIf="!isValidationMode" style="color: #00965E !important;">Soumission de document</span>
</md-card-title>
<md-card-content>
<form novalidate [formGroup]="form">
<h5 style="margin-bottom: -5px">Personne déposant le fichier</h5>
<table>
<tr>
<td>
<p [class.errors]="form.controls.archivist.touched && form.controls.archivist.invalid">
<md-input-container>
<input mdInput placeholder="Identifiant" formControlName="archivist">
<span *ngIf="form.controls.archivist.touched && form.controls.archivist.errors?.required">
<br>L'identifiant de l'archivist est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<p [class.errors]="form.controls.lastname.touched && form.controls.lastname.invalid">
<md-input-container>
<input mdInput placeholder="Nom" formControlName="lastname">
<span *ngIf="form.controls.lastname.touched && form.controls.lastname.errors?.required">
<br>le nom est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<p [class.errors]="form.controls.firstname.touched && form.controls.firstname.invalid">
<md-input-container>
<input mdInput placeholder="Prenom" formControlName="firstname">
<span *ngIf="form.controls.firstname.touched && form.controls.firstname.errors?.required">
<br>le prénom est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<md-input-container>
<input mdInput formControlName="beneficiary" placeholder="Pour le compte de">
</md-input-container>
</td>
</tr>
</table>
<h5 class="sub-title">Identification du document</h5>
<table>
</table>
<table>
<tr>
<td>
<input type="file" (change)="fileChange($event)" formControlName="file" placeholder="Upload file"
accept=".pdf,.doc,.docx">
</td>
<td>
<p [class.errors]="form.controls.title.touched && form.controls.title.invalid">
<md-input-container>
<input mdInput placeholder="Titre" formControlName="title">
<span *ngIf="form.controls.title.touched && form.controls.title.errors?.required">
<br>le titre est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<p [class.errors]="form.controls.format.touched && form.controls.format.invalid">
<md-input-container>
<input mdInput placeholder="Format" formControlName="format">
<span *ngIf="form.controls.format.touched && form.controls.format.errors?.required">
<br>le format est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<p [class.errors]="form.controls.documentid.touched && form.controls.documentid.invalid">
<md-input-container>
<input mdInput placeholder="Identifiant" formControlName="documentid">
<span *ngIf="form.controls.documentid.touched && form.controls.documentid.errors?.required">
<br>l'identifiant est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<p [class.errors]="form.controls.mnesysid.touched && form.controls.mnesysid.invalid">
<md-input-container>
<input mdInput placeholder="Cote" formControlName="mnesysid">
<span *ngIf="form.controls.mnesysid.touched && form.controls.mnesysid.errors?.required">
<br>la cote est obligatoire</span>
</md-input-container>
</p>
</td>
</tr>
</table>
<h5 class="sub-title">Description du document</h5>
<table>
<tr>
<td>
<p [class.errors]="form.controls.name.touched && form.controls.name.invalid">
<md-input-container>
<input mdInput placeholder="Nom" formControlName="name">
<span *ngIf="form.controls.name.touched && form.controls.name.errors?.required">
<br>Le nom est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<md-input-container><input mdInput placeholder="Version" formControlName="version"></md-input-container>
</td>
<td>
<p [class.errors]="form.controls.language.touched && form.controls.language.invalid">
<md-select placeholder="Langue" formControlName="language">
<md-option>None</md-option>
<md-option *ngFor="let language of languages" [value]="language.languageCode">{{ language.frenchLabel
}}
</md-option>
</md-select>
<span *ngIf="form.controls.language.touched && form.controls.language.errors?.required">
<br><br>La langue est obligatoire</span>
</p>
</td>
<td>
<md-select placeholder="Pays" formControlName="country">
<md-option>None</md-option>
<md-option *ngFor="let country of countries" [value]="country.countryCode">{{ country.frenchLabel }}
</md-option>
</md-select>
</td>
</tr>
</table>
<table>
<tr>
<td>
<p [class.errors]="form.controls.summary.touched && form.controls.summary.invalid">
<md-input-container>
<textarea mdInput placeholder="Résumé" formControlName="summary"
class="text-area"></textarea>
<span *ngIf="form.controls.summary.touched && form.controls.summary.errors?.required">
<br>Le résumé est obligatoire</span>
</md-input-container>
</p>
</td>
</tr>
</table>
<table>
<tr>
<td>
<p [class.errors]="form.controls.type.touched && form.controls.type.invalid">
<md-select placeholder="Type" formControlName="type">
<md-option>None</md-option>
<md-option *ngFor="let type of types" [value]="type.typeCode">{{ type.frenchLabel }}</md-option>
</md-select>
<span *ngIf="form.controls.type.touched && form.controls.type.errors?.required">
<br><br>Le type est obligatoire</span>
</p>
</td>
<td>
<md-select placeholder="Sous type" formControlName="subtype">
<md-option>None</md-option>
<md-option *ngFor="let subtype of subtypes" [value]="subtype.subtypeCode">{{ subtype.frenchLabel }}
</md-option>
</md-select>
</td>
<td>
<p [class.errors]="form.controls.entity.touched && form.controls.entity.invalid">
<md-select placeholder="Entité" formControlName="entity">
<md-option>None</md-option>
<md-option *ngFor="let entity of entities" [value]="entity.entityCode">{{ entity.frenchLabel }}
</md-option>
</md-select>
<span *ngIf="form.controls.entity.touched && form.controls.entity.errors?.required">
<br><br>L'entité est obligatoire</span>
</p>
</td>
<td>
<md-select placeholder="Direction" formControlName="management">
<md-option>None</md-option>
<md-option *ngFor="let management of managements" [value]="management.managementCode">{{
management.frenchLabel }}
</md-option>
</md-select>
</td>
<td>
<md-select placeholder="Métier/Service" formControlName="service">
<md-option>None</md-option>
<md-option *ngFor="let service of services" [value]="service.serviceCode">{{ service.frenchLabel }}
</md-option>
</md-select>
</td>
</tr>
</table>
<h5 style="margin-top: 5px;margin-bottom: -5px">Création du document</h5>
<table>
<tr>
<td style="padding-right: 40px;">
<md-radio-group formControlName="isprivate" required>
<md-radio-button value="false" color="primary">Public</md-radio-button>
<md-radio-button value="true" color="primary" [checked]="isprivate">Privé</md-radio-button>
</md-radio-group>
</td>
<td>
<md-form-field>
<input mdInput [mdDatepicker]="creationDatePicker" placeholder="Date de création"
formControlName="creationDate">
<md-datepicker-toggle mdSuffix [for]="creationDatePicker"></md-datepicker-toggle>
<md-datepicker #creationDatePicker></md-datepicker>
</md-form-field>
</td>
<!--<td>-->
<!--<md-form-field>-->
<!--<input mdInput [mdDatepicker]="sendDatePicker" placeholder="Date d'envoi" formControlName="sendDate">-->
<!--<md-datepicker-toggle mdSuffix [for]="sendDatePicker"></md-datepicker-toggle>-->
<!--<md-datepicker #sendDatePicker></md-datepicker>-->
<!--</md-form-field>-->
<!--</td>-->
<!--<td>-->
<!--<md-form-field>-->
<!--<input mdInput [mdDatepicker]="publicationDatePicker" placeholder="Date de passage en public"-->
<!--formControlName="publicyear">-->
<!--<md-datepicker-toggle mdSuffix [for]="publicationDatePicker"></md-datepicker-toggle>-->
<!--<md-datepicker #publicationDatePicker></md-datepicker>-->
<!--</md-form-field>-->
<!--</td>-->
</tr>
</table>
<table>
<tr>
<td>
<p *ngIf="isValidationMode" [class.errors]="form.controls.comment.touched && form.controls.comment.invalid">
<md-input-container>
<textarea mdInput placeholder="Commentaire" formControlName="comment"
class="text-area"></textarea>
<span *ngIf="form.controls.summary.touched && form.controls.comment.errors?.required">
<br>Le commentaire est obligatoire</span>
</md-input-container>
</p>
</td>
</tr>
</table>
</form>
</md-card-content>
<md-card-actions align="end">
<div *ngIf="isValidationMode">
<button md-button align [hidden]="!isValidationMode">Refuser</button>
</div>
<div>
<button md-button type="button" (click)="cancel()">Annuler</button>
</div>
<div>
<button md-button color="primary" type="submit" (click)="submit(form.value)" >
<span *ngIf="!isValidationMode">Soumettre</span>
<span *ngIf="isValidationMode">Valider</span>
</button>
</div>
</md-card-actions>
</md-card>
我尝试从我的模型绑定的日期格式为“2017-06-20T12:00:00.000Z”
你能帮帮我吗?
是否需要安装 dateAdapter?
你的错误:
TypeError: Cannot read property 'invalid' of undefined
其实是这个异常引起的:
Datepicker: value not recognized as a date object by DateAdapter.
这意味着您在模型中使用的日期格式 "2017-06-20T12:00:00.000Z"
不是有效的 Date
实例。参见源代码中的this line。
所以你应该像这样使用 Date
实例:
return new FormGroup({
creationDate: new FormControl(new Date(2017, 6, 20)),
})
或在您的模型中:
model.creationDate = new Date(2017, 6, 20);
另外,如documentations中所述:
Please note: MdNativeDateModule is based off of the functionality
available in JavaScript's native Date object, and is thus not suitable
for many locales. One of the biggest shortcomings of the native Date
object is the inability to set the parse format. We highly recommend
using a custom DateAdapter that works with the formatting/parsing
library of your choice.
您不应该依赖 NativeDateAdapter
,因为它使用的是本机 JavaScript Date
对象,在解析复杂的日期格式方面非常有限。为此,您可以使用很棒的 Moment.js 库。
我正在尝试将 angular material 2 日期选择器与 angular 表单一起使用,但出现此错误:
vendor.bundle.js:92803 ERROR TypeError: Cannot read property 'invalid' of undefined
at MdInput.defaultErrorStateMatcher [as errorStateMatcher] (vendor.bundle.js:121344)
at MdInput.webpackJsonp.../../../material/@angular/material.es5.js.MdInput._updateErrorState (vendor.bundle.js:131778)
at MdInput.webpackJsonp.../../../material/@angular/material.es5.js.MdInput.ngDoCheck (vendor.bundle.js:131739)
at checkAndUpdateDirectiveInline (vendor.bundle.js:102634)
at checkAndUpdateNodeInline (vendor.bundle.js:104132)
at checkAndUpdateNode (vendor.bundle.js:104071)
at prodCheckAndUpdateNode (vendor.bundle.js:104765)
at Object.View_FormComponent_0._co [as updateDirectives] (ng:///AppModule/FormComponent.ngfactory.js:2337)
at Object.updateDirectives (vendor.bundle.js:104522)
at checkAndUpdateView (vendor.bundle.js:104038)
下面是我的组件的代码:
import {Component, OnInit, Output, Input, EventEmitter} from "@angular/core";
import {FormControl, Validators, FormGroup} from "@angular/forms";
import {ReferentialService} from "../shared/referential.service";
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit {
private form: FormGroup;
@Input() model: any;
isValidationMode: boolean;
@Output('cancel') cancel$: EventEmitter<any>;
@Output('submit') submit$: EventEmitter<any>;
// select lists
languages: any;
types: any;
subtypes: any;
entities: any;
managements: any;
countries: any;
services: any;
constructor(private _referentialService: ReferentialService) {
this.submit$ = new EventEmitter();
this.cancel$ = new EventEmitter();
this.model = {};
this.form = this._buildForm();
}
ngOnInit() {
this.initSelectLists();
}
/**
* Function to handle component update
*
* @param record
*/
ngOnChanges(record) {
if (record.model && record.model.currentValue) {
this.model = record.model.currentValue;
this.isValidationMode = !!this.model;
this.form.patchValue(this.model);
}
}
/**
* Function to init select list
*/
initSelectLists() {
this._referentialService.getCountries().subscribe((countries: any[]) => this.countries = countries);
this._referentialService.getLanguages().subscribe((languages: any[]) => this.languages = languages);
this._referentialService.getTypes().subscribe((types: any[]) => this.types = types);
this._referentialService.getSubTypes().subscribe((subtypes: any[]) => this.subtypes = subtypes);
this._referentialService.getEntities().subscribe((entities: any[]) => this.entities = entities);
this._referentialService.getServices().subscribe((services: any[]) => this.services = services);
this._referentialService.getManagements().subscribe((managements: any[]) => this.managements = managements);
}
/**
* Function to emit event to cancel process
*/
cancel() {
this.cancel$.emit();
}
/**
* Function to emit event to submit form and person
*/
submit(doc: any) {
this.submit$.emit(doc);
}
/**
* Function to build our form
*
* @returns {FormGroup}
*
* @private
*/
private _buildForm(): FormGroup {
return new FormGroup({
file: new FormControl('', Validators.compose([])),
documentid: new FormControl('', Validators.compose([Validators.required])),
title: new FormControl('', Validators.compose([Validators.required])),
name: new FormControl('', Validators.compose([Validators.required])),
format: new FormControl('', Validators.compose([Validators.required])),
summary: new FormControl('', Validators.compose([Validators.required])),
mnesysid: new FormControl('', Validators.compose([Validators.required])),
entity: new FormControl('', Validators.compose([Validators.required])),
management: new FormControl('', Validators.compose([])),
service: new FormControl('', Validators.compose([])),
creationDate: new FormControl(null, Validators.compose([])),
sendDate: new FormControl({
value: this.model.creationDate
}, Validators.compose([Validators.required])),
type: new FormControl('', Validators.compose([Validators.required])),
subtype: new FormControl('', Validators.compose([])),
archivist: new FormControl({
value: this.model.archivist,
disabled: true
}, Validators.compose([Validators.required])),
firstname: new FormControl({value: this.model.name, disabled: true}, Validators.compose([Validators.required])),
lastname: new FormControl({
value: this.model.firstname,
disabled: true
}, Validators.compose([Validators.required])),
beneficiary: new FormControl('', Validators.compose([])),
depositid: new FormControl('', Validators.compose([])),
filepath: new FormControl('', Validators.compose([])),
isprivate: new FormControl('', Validators.compose([])),
language: new FormControl('', Validators.compose([Validators.required])),
country: new FormControl('', Validators.compose([])),
publicyear: new FormControl(null, Validators.compose([])),
version: new FormControl('', Validators.compose([])),
status: new FormControl('', Validators.compose([])),
comment: new FormControl('', Validators.compose([Validators.required]))
});
}
}
这是我的 html 代码
<md-card>
<md-card-title>
<span *ngIf="isValidationMode" style="color: #00965E !important;">Validation du document</span>
<span *ngIf="!isValidationMode" style="color: #00965E !important;">Soumission de document</span>
</md-card-title>
<md-card-content>
<form novalidate [formGroup]="form">
<h5 style="margin-bottom: -5px">Personne déposant le fichier</h5>
<table>
<tr>
<td>
<p [class.errors]="form.controls.archivist.touched && form.controls.archivist.invalid">
<md-input-container>
<input mdInput placeholder="Identifiant" formControlName="archivist">
<span *ngIf="form.controls.archivist.touched && form.controls.archivist.errors?.required">
<br>L'identifiant de l'archivist est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<p [class.errors]="form.controls.lastname.touched && form.controls.lastname.invalid">
<md-input-container>
<input mdInput placeholder="Nom" formControlName="lastname">
<span *ngIf="form.controls.lastname.touched && form.controls.lastname.errors?.required">
<br>le nom est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<p [class.errors]="form.controls.firstname.touched && form.controls.firstname.invalid">
<md-input-container>
<input mdInput placeholder="Prenom" formControlName="firstname">
<span *ngIf="form.controls.firstname.touched && form.controls.firstname.errors?.required">
<br>le prénom est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<md-input-container>
<input mdInput formControlName="beneficiary" placeholder="Pour le compte de">
</md-input-container>
</td>
</tr>
</table>
<h5 class="sub-title">Identification du document</h5>
<table>
</table>
<table>
<tr>
<td>
<input type="file" (change)="fileChange($event)" formControlName="file" placeholder="Upload file"
accept=".pdf,.doc,.docx">
</td>
<td>
<p [class.errors]="form.controls.title.touched && form.controls.title.invalid">
<md-input-container>
<input mdInput placeholder="Titre" formControlName="title">
<span *ngIf="form.controls.title.touched && form.controls.title.errors?.required">
<br>le titre est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<p [class.errors]="form.controls.format.touched && form.controls.format.invalid">
<md-input-container>
<input mdInput placeholder="Format" formControlName="format">
<span *ngIf="form.controls.format.touched && form.controls.format.errors?.required">
<br>le format est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<p [class.errors]="form.controls.documentid.touched && form.controls.documentid.invalid">
<md-input-container>
<input mdInput placeholder="Identifiant" formControlName="documentid">
<span *ngIf="form.controls.documentid.touched && form.controls.documentid.errors?.required">
<br>l'identifiant est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<p [class.errors]="form.controls.mnesysid.touched && form.controls.mnesysid.invalid">
<md-input-container>
<input mdInput placeholder="Cote" formControlName="mnesysid">
<span *ngIf="form.controls.mnesysid.touched && form.controls.mnesysid.errors?.required">
<br>la cote est obligatoire</span>
</md-input-container>
</p>
</td>
</tr>
</table>
<h5 class="sub-title">Description du document</h5>
<table>
<tr>
<td>
<p [class.errors]="form.controls.name.touched && form.controls.name.invalid">
<md-input-container>
<input mdInput placeholder="Nom" formControlName="name">
<span *ngIf="form.controls.name.touched && form.controls.name.errors?.required">
<br>Le nom est obligatoire</span>
</md-input-container>
</p>
</td>
<td>
<md-input-container><input mdInput placeholder="Version" formControlName="version"></md-input-container>
</td>
<td>
<p [class.errors]="form.controls.language.touched && form.controls.language.invalid">
<md-select placeholder="Langue" formControlName="language">
<md-option>None</md-option>
<md-option *ngFor="let language of languages" [value]="language.languageCode">{{ language.frenchLabel
}}
</md-option>
</md-select>
<span *ngIf="form.controls.language.touched && form.controls.language.errors?.required">
<br><br>La langue est obligatoire</span>
</p>
</td>
<td>
<md-select placeholder="Pays" formControlName="country">
<md-option>None</md-option>
<md-option *ngFor="let country of countries" [value]="country.countryCode">{{ country.frenchLabel }}
</md-option>
</md-select>
</td>
</tr>
</table>
<table>
<tr>
<td>
<p [class.errors]="form.controls.summary.touched && form.controls.summary.invalid">
<md-input-container>
<textarea mdInput placeholder="Résumé" formControlName="summary"
class="text-area"></textarea>
<span *ngIf="form.controls.summary.touched && form.controls.summary.errors?.required">
<br>Le résumé est obligatoire</span>
</md-input-container>
</p>
</td>
</tr>
</table>
<table>
<tr>
<td>
<p [class.errors]="form.controls.type.touched && form.controls.type.invalid">
<md-select placeholder="Type" formControlName="type">
<md-option>None</md-option>
<md-option *ngFor="let type of types" [value]="type.typeCode">{{ type.frenchLabel }}</md-option>
</md-select>
<span *ngIf="form.controls.type.touched && form.controls.type.errors?.required">
<br><br>Le type est obligatoire</span>
</p>
</td>
<td>
<md-select placeholder="Sous type" formControlName="subtype">
<md-option>None</md-option>
<md-option *ngFor="let subtype of subtypes" [value]="subtype.subtypeCode">{{ subtype.frenchLabel }}
</md-option>
</md-select>
</td>
<td>
<p [class.errors]="form.controls.entity.touched && form.controls.entity.invalid">
<md-select placeholder="Entité" formControlName="entity">
<md-option>None</md-option>
<md-option *ngFor="let entity of entities" [value]="entity.entityCode">{{ entity.frenchLabel }}
</md-option>
</md-select>
<span *ngIf="form.controls.entity.touched && form.controls.entity.errors?.required">
<br><br>L'entité est obligatoire</span>
</p>
</td>
<td>
<md-select placeholder="Direction" formControlName="management">
<md-option>None</md-option>
<md-option *ngFor="let management of managements" [value]="management.managementCode">{{
management.frenchLabel }}
</md-option>
</md-select>
</td>
<td>
<md-select placeholder="Métier/Service" formControlName="service">
<md-option>None</md-option>
<md-option *ngFor="let service of services" [value]="service.serviceCode">{{ service.frenchLabel }}
</md-option>
</md-select>
</td>
</tr>
</table>
<h5 style="margin-top: 5px;margin-bottom: -5px">Création du document</h5>
<table>
<tr>
<td style="padding-right: 40px;">
<md-radio-group formControlName="isprivate" required>
<md-radio-button value="false" color="primary">Public</md-radio-button>
<md-radio-button value="true" color="primary" [checked]="isprivate">Privé</md-radio-button>
</md-radio-group>
</td>
<td>
<md-form-field>
<input mdInput [mdDatepicker]="creationDatePicker" placeholder="Date de création"
formControlName="creationDate">
<md-datepicker-toggle mdSuffix [for]="creationDatePicker"></md-datepicker-toggle>
<md-datepicker #creationDatePicker></md-datepicker>
</md-form-field>
</td>
<!--<td>-->
<!--<md-form-field>-->
<!--<input mdInput [mdDatepicker]="sendDatePicker" placeholder="Date d'envoi" formControlName="sendDate">-->
<!--<md-datepicker-toggle mdSuffix [for]="sendDatePicker"></md-datepicker-toggle>-->
<!--<md-datepicker #sendDatePicker></md-datepicker>-->
<!--</md-form-field>-->
<!--</td>-->
<!--<td>-->
<!--<md-form-field>-->
<!--<input mdInput [mdDatepicker]="publicationDatePicker" placeholder="Date de passage en public"-->
<!--formControlName="publicyear">-->
<!--<md-datepicker-toggle mdSuffix [for]="publicationDatePicker"></md-datepicker-toggle>-->
<!--<md-datepicker #publicationDatePicker></md-datepicker>-->
<!--</md-form-field>-->
<!--</td>-->
</tr>
</table>
<table>
<tr>
<td>
<p *ngIf="isValidationMode" [class.errors]="form.controls.comment.touched && form.controls.comment.invalid">
<md-input-container>
<textarea mdInput placeholder="Commentaire" formControlName="comment"
class="text-area"></textarea>
<span *ngIf="form.controls.summary.touched && form.controls.comment.errors?.required">
<br>Le commentaire est obligatoire</span>
</md-input-container>
</p>
</td>
</tr>
</table>
</form>
</md-card-content>
<md-card-actions align="end">
<div *ngIf="isValidationMode">
<button md-button align [hidden]="!isValidationMode">Refuser</button>
</div>
<div>
<button md-button type="button" (click)="cancel()">Annuler</button>
</div>
<div>
<button md-button color="primary" type="submit" (click)="submit(form.value)" >
<span *ngIf="!isValidationMode">Soumettre</span>
<span *ngIf="isValidationMode">Valider</span>
</button>
</div>
</md-card-actions>
</md-card>
我尝试从我的模型绑定的日期格式为“2017-06-20T12:00:00.000Z”
你能帮帮我吗? 是否需要安装 dateAdapter?
你的错误:
TypeError: Cannot read property 'invalid' of undefined
其实是这个异常引起的:
Datepicker: value not recognized as a date object by DateAdapter.
这意味着您在模型中使用的日期格式 "2017-06-20T12:00:00.000Z"
不是有效的 Date
实例。参见源代码中的this line。
所以你应该像这样使用 Date
实例:
return new FormGroup({
creationDate: new FormControl(new Date(2017, 6, 20)),
})
或在您的模型中:
model.creationDate = new Date(2017, 6, 20);
另外,如documentations中所述:
Please note: MdNativeDateModule is based off of the functionality available in JavaScript's native Date object, and is thus not suitable for many locales. One of the biggest shortcomings of the native Date object is the inability to set the parse format. We highly recommend using a custom DateAdapter that works with the formatting/parsing library of your choice.
您不应该依赖 NativeDateAdapter
,因为它使用的是本机 JavaScript Date
对象,在解析复杂的日期格式方面非常有限。为此,您可以使用很棒的 Moment.js 库。