Angular 11 中的 ngOnIt() 中的属性未获取值
Properties not getting value in ngOnIt() in Angular 11
我正在使用 LeaveService 中的 Api 从数据库获取数据。要获取数据,使用的方法是 LeaveService 中的 applyLeaveGet(id:string)。此方法提供某些值,例如来自数据库的 joiningDate。
我正在使用反应形式的 Angular Material UI。
问题是即使 leave 实例正在获取数据,但是在 ngOnInt() 中,属性没有获取值.ngOnInt() 确实被触发.例如,我收到加入日期未定义的错误。
我该如何解决这个问题。谢谢你的帮助
LeaveService : applyLeaveGet(id:string) 方法
applyLeaveGet(id:string){
return this.http.get<Leave>('https://localhost:44330/api/leave/ApplyLeaveGet/'+ id);
}
ApplyLeave 组件
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup} from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { AuthenticationService } from 'src/app/authentication.service';
import { Leave } from '../interfaces/leave';
import { LeaveService } from '../services/leave.service';
@Component({
selector: 'app-add-edit-leave',
templateUrl: './add-edit-leave.component.html',
styleUrls: ['./add-edit-leave.component.css']
})
export class AddEditLeaveComponent implements OnInit {
form: FormGroup;
currentDate = new Date();
minDate: Date;
maxDate: Date;
selectedFile: File = null;
url : any;
leave :Leave;
constructor(private fb: FormBuilder, private http: HttpClient
,private leaveService : LeaveService
,private route : ActivatedRoute
,private authenticationService: AuthenticationService
) {
leaveService.applyLeaveGet(authenticationService.getUserId())
.subscribe(data =>
this.leave = data
);
// Set the minimum to January 1st 20 years in the past and December 31st a year in the future.
const currentYear = new Date().getFullYear();
this.minDate = new Date(currentYear - 20, 0, 1);
this.maxDate = new Date(currentYear + 1, 11, 31);
}
ngOnInit() {
this.form = this.fb.group({
"currentDate": new FormControl(this.currentDate.toISOString().split("T")[0]),
"joiningDate":[''],
"fromDate":[''],
"tillDate":[''],
"leaveType":[''],
"duration":[''],
"reason":[''],
"filePath":['']
});
}
onSelectFile(event: any) {
this.selectedFile = <File>event.target.files[0];
if (event.target.files && event.target.files[0]) {
var reader = new FileReader();
reader.onload = (event: any) => {
this.url = event.target.result;
}
reader.readAsDataURL(event.target.files[0]);
}
else
{
this.url = "";
}
}
onSubmit(){
var userId = this.authenticationService.getUserId();
const formData = new FormData();
formData.append('userId', userId);
formData.append('currentDate', this.form.value.fullName);
formData.append('joiningDate', this.form.value.fullName);
formData.append('fromDate', this.form.value.fullName);
formData.append('tillDate', this.form.value.fullName);
formData.append('leaveType', this.form.value.fullName);
formData.append('duration', this.form.value.fullName);
formData.append('reason', this.form.value.fullName);
formData.append('balanceAnnualLeave', this.form.value.fullName);
formData.append('balanceSickLeave', this.form.value.fullName);
formData.append('balanceAnnualLeave', this.form.value.fullName);
formData.append('File', this.selectedFile);
}
}
这是html
<p>add-edit-leave works!</p>
<div class="container">
<form class="form-container" [formGroup]="form" (ngSubmit)="onSubmit()">
<mat-card>
<mat-card-header>
<mat-card-title>Apply Leave</mat-card-title>
</mat-card-header>
<mat-card-content>
<div class="row">
<div class="col-md-6">
<mat-form-field class="full-width">
<mat-label>Today's Date</mat-label>
<input formControlName="currentDate" type="date" class="form-control" matInput placeholder="Today's Date" readonly >
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field class="full-width">
<mat-label>Joining Date</mat-label>
<input formControlName="joiningDate" type="datetime" class="form-control" matInput placeholder="Joining Date">
</mat-form-field>
</div>
</div>
<!--Date Requested For-->
<div class="row">
<div class="col-md-6">
<mat-form-field class="full-width" appearance="fill">
<mat-label>From Date</mat-label>
<input matInput formControlName="fromDate" [min]="minDate" [max]="maxDate"
[matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field class="full-width" appearance="fill">
<mat-label>Till Date</mat-label>
<input matInput formControlName="tillDate" [min]="minDate" [max]="maxDate"
[matDatepicker]="pickerTillDate">
<mat-datepicker-toggle matSuffix [for]="pickerTillDate"></mat-datepicker-toggle>
<mat-datepicker #pickerTillDate></mat-datepicker>
</mat-form-field>
</div>
</div>
<!--Leave Type Duration(dropdown box)-->
<div class="row">
<div class="col-md-6">
<mat-form-field class="full-width" appearance="fill">
<mat-label>Leave Type</mat-label>
<select formControlName="leaveType" matNativeControl id="mySelectId">
<option value="" disabled selected></option>
<option value="Annual Leave">Annual Leave</option>
<option value="Sick Leave">Sick Leave</option>
</select>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field class="full-width" appearance="fill">
<mat-label>Duration</mat-label>
<select formControlName="duration" matNativeControl id="mySelectId">
<option value="" disabled selected></option>
<option value="Full Day ">Full Day</option>
<option value="First Half Day">First Half Day</option>
<option value="Second Half Day">Second Half Day</option>
</select>
</mat-form-field>
</div>
</div>
<!--Reason-->
<div class="row">
<div class="col-md-12">
<mat-form-field class="full-width">
<mat-label>Reason</mat-label>
<input formControlName="reason" matInput placeholder="Reason">
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-md-6">
<mat-label>Leave Balacne</mat-label><br>
<ul>
<li>
annualLeaveBalacne: <span>{{leave.balanceAnnualLeave}}</span> <br>
</li>
<li>
sickLeaveBalance: <span>{{leave.balanceSickLeave}}</span>
</li>
</ul>
</div>
</div>
<!--Submit-->
<mat-card-actions>
<button mat-stroked-button type="submit>Basic</button>
</mat-card-actions>
</mat-card-content>
</mat-card>
</form>
</div>
在您的问题的当前版本中,您似乎没有在 OnInit
的表单中使用 this.leave
中的任何设置值。根据您的问题描述和其余代码,我认为您的问题是 LeaveService
在构造函数中的异步调用。由于它是异步代码,因此在调用和执行 ngOnInit
之前可能无法完成,因此会出现有关未定义值的错误消息。您必须等到 HTTP 调用完成才能访问数据。
由于您不应在构造函数中执行可能较长的 运行 HTTP 调用,因此我建议将该部分移动到 OnInit
中。所有不长运行和异步的都可以在构造函数中执行。您的代码可以这样重构:
constructor(private fb: FormBuilder,
private http: HttpClient,
private leaveService : LeaveService,
private route : ActivatedRoute,
private authenticationService: AuthenticationService
) {
// Set the minimum to January 1st 20 years in the past and December 31st a year in the future.
const currentYear = new Date().getFullYear();
this.minDate = new Date(currentYear - 20, 0, 1);
this.maxDate = new Date(currentYear + 1, 11, 31);
this.form = this.fb.group({
"currentDate": new FormControl(this.currentDate.toISOString().split("T")[0]),
"joiningDate": [''],
"fromDate": [''],
"tillDate": [''],
"leaveType": [''],
"duration": [''],
"reason": [''],
"filePath": ['']
});
}
ngOnInit() {
leaveService.applyLeaveGet(authenticationService.getUserId())
.subscribe(data =>
{
this.leave = data;
// now data is here and can be used to set initial form values, example:
this.form.get('leaveType').setValue(this.leave.Type);
}
);
}
我正在使用 LeaveService 中的 Api 从数据库获取数据。要获取数据,使用的方法是 LeaveService 中的 applyLeaveGet(id:string)。此方法提供某些值,例如来自数据库的 joiningDate。 我正在使用反应形式的 Angular Material UI。
问题是即使 leave 实例正在获取数据,但是在 ngOnInt() 中,属性没有获取值.ngOnInt() 确实被触发.例如,我收到加入日期未定义的错误。 我该如何解决这个问题。谢谢你的帮助
LeaveService : applyLeaveGet(id:string) 方法
applyLeaveGet(id:string){
return this.http.get<Leave>('https://localhost:44330/api/leave/ApplyLeaveGet/'+ id);
}
ApplyLeave 组件
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup} from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { AuthenticationService } from 'src/app/authentication.service';
import { Leave } from '../interfaces/leave';
import { LeaveService } from '../services/leave.service';
@Component({
selector: 'app-add-edit-leave',
templateUrl: './add-edit-leave.component.html',
styleUrls: ['./add-edit-leave.component.css']
})
export class AddEditLeaveComponent implements OnInit {
form: FormGroup;
currentDate = new Date();
minDate: Date;
maxDate: Date;
selectedFile: File = null;
url : any;
leave :Leave;
constructor(private fb: FormBuilder, private http: HttpClient
,private leaveService : LeaveService
,private route : ActivatedRoute
,private authenticationService: AuthenticationService
) {
leaveService.applyLeaveGet(authenticationService.getUserId())
.subscribe(data =>
this.leave = data
);
// Set the minimum to January 1st 20 years in the past and December 31st a year in the future.
const currentYear = new Date().getFullYear();
this.minDate = new Date(currentYear - 20, 0, 1);
this.maxDate = new Date(currentYear + 1, 11, 31);
}
ngOnInit() {
this.form = this.fb.group({
"currentDate": new FormControl(this.currentDate.toISOString().split("T")[0]),
"joiningDate":[''],
"fromDate":[''],
"tillDate":[''],
"leaveType":[''],
"duration":[''],
"reason":[''],
"filePath":['']
});
}
onSelectFile(event: any) {
this.selectedFile = <File>event.target.files[0];
if (event.target.files && event.target.files[0]) {
var reader = new FileReader();
reader.onload = (event: any) => {
this.url = event.target.result;
}
reader.readAsDataURL(event.target.files[0]);
}
else
{
this.url = "";
}
}
onSubmit(){
var userId = this.authenticationService.getUserId();
const formData = new FormData();
formData.append('userId', userId);
formData.append('currentDate', this.form.value.fullName);
formData.append('joiningDate', this.form.value.fullName);
formData.append('fromDate', this.form.value.fullName);
formData.append('tillDate', this.form.value.fullName);
formData.append('leaveType', this.form.value.fullName);
formData.append('duration', this.form.value.fullName);
formData.append('reason', this.form.value.fullName);
formData.append('balanceAnnualLeave', this.form.value.fullName);
formData.append('balanceSickLeave', this.form.value.fullName);
formData.append('balanceAnnualLeave', this.form.value.fullName);
formData.append('File', this.selectedFile);
}
}
这是html
<p>add-edit-leave works!</p>
<div class="container">
<form class="form-container" [formGroup]="form" (ngSubmit)="onSubmit()">
<mat-card>
<mat-card-header>
<mat-card-title>Apply Leave</mat-card-title>
</mat-card-header>
<mat-card-content>
<div class="row">
<div class="col-md-6">
<mat-form-field class="full-width">
<mat-label>Today's Date</mat-label>
<input formControlName="currentDate" type="date" class="form-control" matInput placeholder="Today's Date" readonly >
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field class="full-width">
<mat-label>Joining Date</mat-label>
<input formControlName="joiningDate" type="datetime" class="form-control" matInput placeholder="Joining Date">
</mat-form-field>
</div>
</div>
<!--Date Requested For-->
<div class="row">
<div class="col-md-6">
<mat-form-field class="full-width" appearance="fill">
<mat-label>From Date</mat-label>
<input matInput formControlName="fromDate" [min]="minDate" [max]="maxDate"
[matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field class="full-width" appearance="fill">
<mat-label>Till Date</mat-label>
<input matInput formControlName="tillDate" [min]="minDate" [max]="maxDate"
[matDatepicker]="pickerTillDate">
<mat-datepicker-toggle matSuffix [for]="pickerTillDate"></mat-datepicker-toggle>
<mat-datepicker #pickerTillDate></mat-datepicker>
</mat-form-field>
</div>
</div>
<!--Leave Type Duration(dropdown box)-->
<div class="row">
<div class="col-md-6">
<mat-form-field class="full-width" appearance="fill">
<mat-label>Leave Type</mat-label>
<select formControlName="leaveType" matNativeControl id="mySelectId">
<option value="" disabled selected></option>
<option value="Annual Leave">Annual Leave</option>
<option value="Sick Leave">Sick Leave</option>
</select>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field class="full-width" appearance="fill">
<mat-label>Duration</mat-label>
<select formControlName="duration" matNativeControl id="mySelectId">
<option value="" disabled selected></option>
<option value="Full Day ">Full Day</option>
<option value="First Half Day">First Half Day</option>
<option value="Second Half Day">Second Half Day</option>
</select>
</mat-form-field>
</div>
</div>
<!--Reason-->
<div class="row">
<div class="col-md-12">
<mat-form-field class="full-width">
<mat-label>Reason</mat-label>
<input formControlName="reason" matInput placeholder="Reason">
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-md-6">
<mat-label>Leave Balacne</mat-label><br>
<ul>
<li>
annualLeaveBalacne: <span>{{leave.balanceAnnualLeave}}</span> <br>
</li>
<li>
sickLeaveBalance: <span>{{leave.balanceSickLeave}}</span>
</li>
</ul>
</div>
</div>
<!--Submit-->
<mat-card-actions>
<button mat-stroked-button type="submit>Basic</button>
</mat-card-actions>
</mat-card-content>
</mat-card>
</form>
</div>
在您的问题的当前版本中,您似乎没有在 OnInit
的表单中使用 this.leave
中的任何设置值。根据您的问题描述和其余代码,我认为您的问题是 LeaveService
在构造函数中的异步调用。由于它是异步代码,因此在调用和执行 ngOnInit
之前可能无法完成,因此会出现有关未定义值的错误消息。您必须等到 HTTP 调用完成才能访问数据。
由于您不应在构造函数中执行可能较长的 运行 HTTP 调用,因此我建议将该部分移动到 OnInit
中。所有不长运行和异步的都可以在构造函数中执行。您的代码可以这样重构:
constructor(private fb: FormBuilder,
private http: HttpClient,
private leaveService : LeaveService,
private route : ActivatedRoute,
private authenticationService: AuthenticationService
) {
// Set the minimum to January 1st 20 years in the past and December 31st a year in the future.
const currentYear = new Date().getFullYear();
this.minDate = new Date(currentYear - 20, 0, 1);
this.maxDate = new Date(currentYear + 1, 11, 31);
this.form = this.fb.group({
"currentDate": new FormControl(this.currentDate.toISOString().split("T")[0]),
"joiningDate": [''],
"fromDate": [''],
"tillDate": [''],
"leaveType": [''],
"duration": [''],
"reason": [''],
"filePath": ['']
});
}
ngOnInit() {
leaveService.applyLeaveGet(authenticationService.getUserId())
.subscribe(data =>
{
this.leave = data;
// now data is here and can be used to set initial form values, example:
this.form.get('leaveType').setValue(this.leave.Type);
}
);
}