2016-08-01 5 views
1

私は、クライアントキーが一意であるかどうかを確認する検証指令を持っています。ネットワークのトラフィックを確認してすべてのキーストロークを呼び出すまで、すべてが期待どおりに機能するようです。Angular2 RC4 debounceTimeはすべてのキーストロークを呼び出します。

あなたが見ることができるように
this.domainForm = this.fb.group({ 
     clientKey: ['', Validators.required, new RefIdValidatorDirective(this.domainService).validator] 
    }); 

、これは効率的ではありませんどちらか私は、検証に親コンポーネントからのDomainServiceを渡していますように:

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

私は、モデル駆動型フォームでこの検証ディレクティブを使用していますしかし、私はこのディレクティブにサービスを注入する方法を決めることができませんでした。ここで

は私のネットワークトレースは、私が速くタイピングしていたとしても、次のようになります。

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

これですべてのヘルプは高く評価されます。

答えて

1

コードに問題があります:Observableを返信していませんが、Subscriptionを返信しています。購読して戻っているためです。

これを実行するには、各キーストロークをデバウンスするには、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方法でメモリをクリーンアップします。

関連する問題