我正在尝试使用角度形式的角度素材2 datepicker,我收到此错误:
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?答案 0 :(得分:6)
您的错误:
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中所述:
请注意:MdNativeDateModule基于该功能 在JavaScript的本机Date对象中可用,因此不适用 对于许多语言环境。原生日期的最大缺点之一 object是无法设置解析格式。我们强烈推荐 使用适用于格式化/解析的自定义DateAdapter 您选择的图书馆。
您不应该依赖NativeDateAdapter
,因为它使用本机JavaScript Date
对象,这在解析复杂日期格式时非常有限。为此,您可以使用令人敬畏的Moment.js库。