angular - пользовательский валидатор с http-вызовом - PullRequest
0 голосов
/ 29 мая 2018

Я воссоздал проблему здесь

https://stackblitz.com/edit/angular-custom-validator-issue

Вы можете разветвить настройку (вверху справа) и затем отредактировать, как вам угодно

В основном я пытаюсьсоздайте пользовательский валидатор в моей настройке реактивной формы, который принимает значение ввода формы и отправляет http-запрос в API Datamuse, который подсчитывает количество слогов в строке.Затем в зависимости от результата ответа я возвращаю либо ошибку, либо успех.Я следовал угловым документам, но у меня есть проблемы с вызовом http, который, как я полагаю, как-то связан с порядком стека вызовов.Поэтому мне нужна помощь в том, как я могу достичь этого, я думаю, что это поможет мне немного лучше понять Angular.

app.component

import { Component, ElementRef } from '@angular/core';
import { FormControl, FormBuilder, FormGroup, Validators, AbstractControl } from '@angular/forms';
import { VERSION } from '@angular/material';
import { SyllableCountValidator } from './syllable-count.service';

@Component({
  selector: 'material-app',
  templateUrl: 'app.component.html'
})
export class AppComponent {
  version = VERSION;
  public poemForm: FormGroup;

  constructor(private fb: FormBuilder, private scv: SyllableCountValidator) {
    this.createForm();
  }

  //ERRORS APPEAR IN CONSOLE after INPUT into 'input text' in the dom

  // 1. create form group with entry inputText. Initialise it with no value 
  // and set the validation to a custom validator called 'count' that is 
  // located in the 'private scv: SyllableCountValidator' service
  // go to syllable-count.service file to see next steps
  createForm() {
    this.poemForm = this.fb.group({
          inputText: ['', [this.scv.count]],
      });
  }
}

syllable-count.service

    import { ValidatorFn, AbstractControl, FormControl } from '@angular/forms';
    import { forEach } from '@angular/router/src/utils/collection';
    import { Injectable } from '@angular/core';
    import { HttpClient, HttpResponse } from '@angular/common/http';
    import { Observable } from 'rxjs';

    @Injectable()
    export class SyllableCountValidator {

        constructor(private http: HttpClient) {}

        // 2. create http request to datamuse API that returns a syllable 
        // count repsonse for requested text
        public requestCount(text): Observable<Object> {
            return this.http.get(`https://api.datamuse.com/words?sp=${text}&md=s`) as Observable<Object>;
        }

        // 3. on any input into the formControl 'inputText' this will fire
        public count(control: FormControl) {

          // 4. split the string received from the fromControl 
          // 'textInput' into an array
          const arrayOfStrings = control.value.split(' ');

          // 5. define empty text variable
          let text = '';

          // 6. loop through step 3. arrayOfStrings and concatonate into 
          // correct format for http call and push to text variable in step 4.
          const pushToText = Array.prototype.forEach.call(arrayOfStrings, function(word) {
              text = `${text}+${word}`;
          });

          // 7. trim first character of text variable in step 4. to remove
          // unessecary '+' character
          const trimmedText = text.substr(1);

          // 8. call requestCount() in step 2. and return validation result
          if (trimmedText) {
            const validateSyllables = this.requestCount(trimmedText).subscribe((response) => {
              // 8.1.1 if syllable count is greater than 5 return error
              // of number of syllables it is greater by
              if ( response[0].numSyllables > 5 ) {
                return {
                  error: 5 - response[0].numSyllables
                }
              // 8.1.2 if syllable count is less than 5 return error
              // of number of syllables it is less by
              } else if ( response[0].numSyllables > 5 ) {
                return {
                  error: 5 - response[0].numSyllables
                }
              // 8.1.3 if syllable count equals 5 return validation
              // success as required by angular of 'null'
              } else if ( response[0].numSyllables == 5 ) {
                return null;
              }
            });

            // 9.2. return validation result
            return validateSyllables;      
          }
      }
    }

1 Ответ

0 голосов
/ 29 мая 2018

У вас проблема с «this», которая не указывает на правильную область действия.

«Простое» исправление - это использование жирной стрелки в вашем поставщике услуг таким образом, чтобы убедиться, что «this» указывает напоставщик услуг:

вместо:

public count(control: FormControl) {

do:

public count = (control: FormControl) => {

Теперь ваш код по-прежнему нуждается в другомустранены проблемы (например, разбор объекта ответа недопустим).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...