validare - Injectați un serviciu într-un validator personalizat în Angular2


Încerc să folosesc un serviciu într-un validator personalizat pentru a verifica dacă un nume de utilizator există deja.

import {Component} from 'angular2/core';
import {
    Control,
    ControlGroup,
    FormBuilder
} from "angular2/common";
import {CharacterService} from "./character-service";

@Component({
    selector: 'register-character-form',
    template: `
        <h2 class="ui header">A new adventurer is coming...</h2>
        <form (ngSubmit)="register()" [ngFormModel]="characterForm" class="ui form">
            <div class="field">
                <label>Nom</label>
                <input ngControl="name">
            </div>
            <button type="submit" class="ui button">Enter in the adventure</button>
        </form>
    `,
    providers: [CharacterService]
})
export class RegisterCharacterFormCmp {
    characterForm: ControlGroup;
    name: Control;

    constructor(private _characterService: CharacterService, fb: FormBuilder) {
        this.name = fb.control('', this.characterNameValidator);

        this.characterForm = fb.group({
            name: this.name
        });
    }

    register(): void {
        //TODO: To implement
    }

    // Not works, this binds the control
    characterNameValidator(control: Control) {
        return this._characterService.isCharacterNameAlreadyExists(control.value) ? {nameCharacterAlreadyExistsError: true} : null;
    }
}

Nu funcționează. În characterNameValidator, 'this' face referire la control și nu la clasa mea. Serviciul este nedefinit. Cum pot să folosesc serviciul meu în validator?

Mai global, cum pot să transmit argumente într-un validator personalizat?

Răspuns #1

Trebuie să controlezi ce înseamnă this în validarea ta. Poți face acest lucru cu bind

this.name = fb.control('', this.characterNameValidator.bind(this));

Atunci totul celălalt ar trebui să funcționeze conform așteptărilor.

Răspunsul #2

Poți folosi o funcție săgeată pentru a păstra contextul neschimbat.

this.name = fb.control('', (control: Control) => this.characterNameValidator(control));