2016-08-01 57 views
1

我有一個驗證指令,用於檢查客戶端密鑰是否唯一。一切似乎都按預期工作,直到我檢查網絡流量並查看它是否正在爲每次按鍵撥打電話。Angular2 RC4 debounceTime每個擊鍵都會調用

import { Directive, forwardRef, ReflectiveInjector } from '@angular/core'; 
import { AbstractControl } from '@angular/common'; 
import { FormControl, NG_VALIDATORS } from '@angular/forms'; 

import {Observable} from 'rxjs/Rx'; 

import {DomainService} from '../services/domain.service'; 

interface IRefIdValidator { 
} 

function validateRefIdFactory(domainService : DomainService) { 
    return (control: AbstractControl): Observable<IRefIdValidator> => { 

    // get the domain Id and Ref Id key 
    let domainId: number = +control.root.find('domainId').value; 
    let clientId: number = +control.root.find('clientId').value; 
    let key: string = control.value; 

    // Return an observable with null if the 
    // reference id check comes back successful 
    return new Observable((obs: any) => { 
     control 
     .valueChanges 
     .debounceTime(500) 
     .distinctUntilChanged() 
     .flatMap(value => domainService.checkDomainClientKey(domainId, clientId, key)) 
     .subscribe(
     data => { 
      obs.next(null); 
      obs.complete(); 
     }, 
     error => { 
      obs.next({ refId: true }); 
      obs.complete(); 
     } 
     ); 
    }); 
    }; 
} 

@Directive({ 
    selector: '[validateRefId][formControlName],[validateRefId][ngModel],[validateRefId][formControl]', 
    providers: [ 
    DomainService, 
    { provide: NG_VALIDATORS, useExisting: forwardRef(() => RefIdValidatorDirective), multi: true } 
    ] 
}) 
export class RefIdValidatorDirective { 
    validator: Function; 

    constructor(
    private domainService: DomainService 
    ) { 
     console.log('RefIdValidatorDirective created'); 
    this.validator = validateRefIdFactory(this.domainService); 
    } 

    validate(c: AbstractControl) { 
    return this.validator(c); 
    } 
} 

我使用的模型驅動形式,這個驗證指令:

this.domainForm = this.fb.group({ 
     clientKey: ['', Validators.required, new RefIdValidatorDirective(this.domainService).validator] 
    }); 

正如你所看到的,這是沒有效率的無論是作爲我傳遞的DomainService從父組件驗證指令,但是,我一直無法弄清楚如何以任何其他方式將服務注入此指令。

這裏是我的網絡跟蹤的樣子,儘管我打字快:

24?key=Test 
24?key=TestA 
24?key=TestAB 
24?key=TestABC 

任何幫助表示讚賞。

回答

1

您的代碼存在問題:您未返回Observable,而是返回Subscription,因爲您正在訂閱並返回。

要做到這一點,最好創建s Subject來消除每個擊鍵。這是一個很好的做法,可以適應您的需求。該onSearch方法被調用每次擊鍵:

import { Component, OnInit, OnDestroy } from '@angular/core'; 
import { Subscription } from 'rxjs/Subscription'; 

@Component({...}) 
export class ExampleComponent implements OnInit, OnDestroy { 
private searchTermStream = new Subject<string>(); 
private searchSubscription: Subscription; 

    ngOnInit() { 
    this.searchSubscription = this.createInputSubscriber(); 
    } 

    ngOnDestroy() { 
    this.searchTermStream.complete(); 
    } 

    onSearch(query: string): void { 
    this.searchTermStream.next(query); 
    } 

    private createInputSubscriber(): Subscription { 
    return this.searchTermStream 
     .distinctUntilChanged() 
     .debounceTime(500) 
     .subscribe((query: string) => console.log(query)); 
    } 
} 

當組件被銷燬這裏我們也清理了ngOnDestroy方法記憶。

相關問題