typescript - Angular 2 FormBuilder Örneği Oluşturulurken Hata


(Kod düzeltme ile güncellendi)

Bir form oluşturmaya ve bir kontrol grubuna doğrulama eklemeye çalışıyorum, böylece iki kontrolün kombinasyonunun bir nesne dizisinde olup olmadığını kontrol edebilirim. Aşağıdaki koda sahibim, ancak sayfamı çalıştırmaya çalıştığımda bana bir hata veriyor.

İSTİSNASI: ClientFormComponent oluşturulurken hata!. ORİJİNAL İSTİSNA: TypeError: Tanımsız olanın 'length' özelliği okunamıyor

Dizimin length özelliğine neden erişemediğimden emin değilim. Servisimin "getClients()" yöntemi uygulamamın başka yerlerinde mükemmel çalışıyor. Herhangi bir düşünce harika olurdu.

@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 };
    }
}

Şablon HTML'im:

<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 &amp; Name Combo Already Exist</div>
    </form>
</div>

Cevap #1

Çünkü getClients() bir gözlemlenebilir olduğundan, uzunluğu subscribe geri çağrısı içinde ayarlamanız gerekir.

var clis: Client[];
var length = 0;
this._clientService.getClients().subscribe(clients => {
    clis = clients;
    length = clis.length;
});

Bu, veriler aboneliğinize geri döndüğünde uzunluğun doğru şekilde ayarlanmasını sağlar.

Hatanın ilk etapta neden oluştuğuna gelince, dizinizi başlatmamışsınız. Şu an tanımsız olduğu için uzunluğunu kontrol etmeye çalıştığınızda hata verdiği için aslında bir varsayılan değer sağlamanız gerekir.

var clis: Client[] = [];

Cevap #2

Sanırım asenkron bir doğrulayıcı uygulamaya çalışıyorsunuz. Bunun yerine validator yerine asyncValidator özniteliğini kullanmalısınız:

_fb.group({
  'name': ['', Validators.compose([Validators.required])],
  'npi': ['', Validators.compose([Validators.required, (...)])]
}, { asyncValidator: this.npiNameDupValidator.bind(this) });

Doğrulayıcınızı şu şekilde yeniden düzenlerdim:

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);
      }
  });
}