تایپاسکریپت - خطای FormBuilder در Angular 2 هنگام نمونهسازی
(کد با اصلاح بهروزرسانی شد)
من در تلاش هستم که یک فرم بسازم و اعتبارسنجی را به یک گروه کنترل اضافه کنم تا بتوانم بررسی کنم که آیا ترکیب دو کنترل در یک آرایه از اشیاء وجود دارد یا خیر. من کد زیر را دارم، اما وقتی سعی میکنم صفحه خود را اجرا کنم، خطا میدهد.
استثنا: خطا در زمان ایجاد نمونهی ClientFormComponent! استثنای اصلی: TypeError: نمیتوان ویژگی 'length' را از undefined خواند
من مطمئن نیستم چرا نمیتواند به ویژگی طول آرایه من دسترسی پیدا کند. متد "getClients()" سرویس من در جای دیگری از برنامه من به خوبی کار میکند. هر نظری مفید خواهد بود.
@Component({
selector: 'client-form',
templateUrl: './Scripts/typescript/client-form.component.html',
directives: [FORM_DIRECTIVES],
providers: [ClientService]
})
export class ClientFormComponent
{
clientForm: ControlGroup;
npi: AbstractControl;
name: AbstractControl;
constructor(private _clientService: ClientService, _fb: FormBuilder) {
this.clientForm = _fb.group({ 'name': ['', Validators.compose([Validators.required])], 'npi': ['', Validators.compose([Validators.required, npiNumValidator, Validators.maxLength(10), Validators.minLength(10)])] }, { asyncValidator: this.npiNameDupValidator.bind(this) });
this.name = this.clientForm.controls['name'];
this.npi = this.clientForm.controls['npi'];
}
clientList: Client[];
active = true;
onSubmit(value: Client) {
this._clientService.addDeleteClient(value, true)
.subscribe(
client => this.clientList.push(client));
}
npiNameDupValidator(group: ControlGroup) {
return new Promise((resolve, reject) => {
let name = group.controls['name'];
let npi = group.controls['npi'];
var found = false;
this._clientService.getClients().subscribe(clients => {
for (var i = 0; i < clients.length; i++) {
alert(clients[i].name + ':' + name.value);
alert(clients[i].npi + ':' + npi.value);
if (clients[i].name == name.value && clients[i].npi == npi.value) {
found = true;
break;
}
}
if (found) {
alert('Found!');
resolve({ npiNameDupe: true });
}
else {
resolve(null);
}
});
});
}
}
function npiNumValidator(control: Control): { [s: string]: boolean } {
if (isNaN(control.value)) {
return { npiNAN: true };
}
}قالب HTML من:
<div class="container">
<form *ngIf="active" (ngSubmit)="onSubmit(clientForm.value)" [ngFormModel]="clientForm">
<div class="form-group" style="float: left;">
<label for="clientid">Client Id:</label>
<input placeholder="QDX"id="clientid" type="text" class="form-control" [ngFormControl]="clientForm.controls['name']">
<div *ngIf="name.hasError('required') && name.touched"
class="alert alert-danger">Client ID is required</div>
<div *ngIf="name.hasError('npiNAN')"
class="alert alert-danger">NPI must be a number</div>
</div>
<div class="form-group" style="float: left; padding-left: 10px;">
<label for="npi">NPI:</label>
<input placeholder="0123456789" maxlength="10" id="npi" type="text" class="form-control" [ngFormControl]="clientForm.controls['npi']">
<div *ngIf="npi.hasError('required') && npi.touched"
class="alert alert-danger">NPI is required</div>
<div *ngIf="npi.hasError('npiNAN') && npi.touched"
class="alert alert-danger">NPI must be a number</div>
<div *ngIf="npi.hasError('minlength') && npi.touched"
class="alert alert-danger">NPI must be 10 characters</div>
</div>
<div style="float: left; margin: 25px 0 0 10px;">
<button type="submit" class="btn btn-default" [disabled]="!clientForm.valid">Add</button>
</div>
<br style="clear:both;" />
<div *ngIf="clientForm.hasError('npiNameDupe')"
class="alert alert-danger">NPI & Name Combo Already Exist</div>
</form>
</div>پاسخ شماره ۱
از آنجا که getClients() یک Observable است، شما نیاز دارید طول را داخل callback مربوط به subscribe تنظیم کنید.
var clis: Client[];
var length = 0;
this._clientService.getClients().subscribe(clients => {
clis = clients;
length = clis.length;
});
این اطمینان میدهد که طول بهطور صحیح تنظیم شود زمانی که دادهها به اشتراک شما بازگردانده میشوند.
در مورد اینکه چرا در ابتدا خطا را دریافت میکنید، شما آرایه خود را مقداردهی اولیه نکردهاید. شما باید در واقع یک مقدار پیشفرض ارائه دهید زیرا در حال حاضر مقدار آن تعریف نشده است و وقتی سعی میکنید طول آن را بررسی کنید، خطا ایجاد میشود.
var clis: Client[] = [];
پاسخ شماره ۲
من فکر میکنم که شما سعی دارید یک اعتبارسنج غیرهمزمان را پیادهسازی کنید. شما باید به جای ویژگی validator از ویژگی asyncValidator استفاده کنید:
_fb.group({
'name': ['', Validators.compose([Validators.required])],
'npi': ['', Validators.compose([Validators.required, (...)])]
}, { asyncValidator: this.npiNameDupValidator.bind(this) });
من اعتبارسنج شما را به این شکل بازسازی میکنم:
npiNameDupValidator(group: ControlGroup) {
return new Promise((resolve, reject) => {
let name = group.controls['name'];
let npi = group.controls['npi'];
this._clientService.getClients().subscribe(clients => {
var clis = clients;
var length = clis.length;
var found = (...); // your processing here
if (found) {
resolve({ npiNameDupe: true });
} else {
resolve(null);
}
});
}
