Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html Angular 4:如何对来自后端的数据使用自定义验证器_Html_Angular_Typescript - Fatal编程技术网

Html Angular 4:如何对来自后端的数据使用自定义验证器

Html Angular 4:如何对来自后端的数据使用自定义验证器,html,angular,typescript,Html,Angular,Typescript,在表单中,只有当表单有效时,“提交”按钮才变为“启用”。特定的输入包含带有后端数据的datalist。如果用户填写的数据不在数据列表中,我想返回无效的表单。所以,我需要一个自定义验证器来检查用户数据是否等于来自后端的数据。 后端数据是包含参考号和其他数据的对象列表 因此,我尝试在同一组件文件中为自定义验证器创建一个函数,但由于以下两个原因,该函数不起作用: 我不知道如何检索我的物品列表“refere.refNumber.input”的路径 我在控制台中遇到错误:“无法读取未定义的属性'leng

在表单中,只有当表单有效时,“提交”按钮才变为“启用”。特定的输入包含带有后端数据的datalist。如果用户填写的数据不在数据列表中,我想返回无效的表单。所以,我需要一个自定义验证器来检查用户数据是否等于来自后端的数据。 后端数据是包含参考号和其他数据的对象列表

因此,我尝试在同一组件文件中为自定义验证器创建一个函数,但由于以下两个原因,该函数不起作用:

  • 我不知道如何检索我的物品列表“refere.refNumber.input”的路径

  • 我在控制台中遇到错误:“无法读取未定义的属性'length'

自定义验证器的函数:

export function ValidateRefNumber(control: AbstractControl) {
  for (let refer of ArbologistiqueComponent.listOfArticles) {
     if (control.value == refer.refNumber.input) {
        return true;
     }
  }
  return null;
}
我的整个组件。ts

import { Component, OnInit } from '@angular/core';
import 'rxjs/add/operator/switchMap';
import { ManagementArbologistiqueService } from "../management-arbologistique.service";
import { ActivatedRoute, Params } from '@angular/router';
import { FormGroup, FormControl, FormBuilder, FormArray, Validators } from '@angular/forms';

@Component({
  selector: 'app-arbologistique',
  templateUrl: './arbologistique.component.html',
  styleUrls: ['./arbologistique.component.css']
})

export class ArbologistiqueComponent implements OnInit {

  private reponseTest: String;
  private listOfArticles :Array<Object>
  private pathDownload: any;
  private myFormGroup: FormGroup;
  fileToUpload: File = null;
  private buttonSubmitEnabled: boolean = false;

  constructor(public fb: FormBuilder, private managementArbo: ManagementArbologistiqueService, private route: ActivatedRoute) { }

  ngOnInit() {
    this.myFormGroup = this.fb.group({
      itemRows: this.fb.array([this.initItemRows()])
    })

    this.myFormGroup.valueChanges.subscribe(x => this.buttonSubmitEnabled = false);
    this.getListBdd();
      }


  initItemRows() {
    return this.fb.group({
      ... //other fields
      refNb: ['',[Validators.required, ValidateRefNumber]],
      ... //other fields

    })
  }

  addRow(index: number) {
    console.log("functionAddRow called");
    const control = <FormArray>this.myFormGroup.controls['itemRows'];
    control.insert(index, this.initItemRows());

  }

  deleteRow(index: number) {
    console.log("functionDeleteRow called");
    const control = <FormArray>this.myFormGroup.controls['itemRows'];
    control.removeAt(index);
  }

  sendForm() {
    this.buttonSubmitEnabled=true;
    console.log("functionExportCalled");
    this.route.params.subscribe((params: Params) => {
      let subroute = "exportation";
      this.managementArbo.postProducts(subroute, JSON.stringify(this.myFormGroup.value))
        .subscribe(
          res => { this.reponseTest = res; console.log('reponse:' + res); }

          ,
          err => console.log(err),
          () => console.log('getProducts done'));

    });
  }

  getListBdd() {
    this.route.params.subscribe((params: Params) => {
      let subroute = "getRefNumber";
      this.managementArbo.getProducts(subroute)
        .subscribe(
          res => { this.listOfArticles = res; console.log('reponse:' + res); }

          ,
          err => console.log(err),
          () => console.log('getProducts done'));
    });
  }

  get refNb() {
    return this.myFormGroup.get('itemRows.refNb');
} 
}

export function ValidateRefNumber(control: AbstractControl) {
      for (let refer of ArbologistiqueComponent.listOfArticles) {
         if (control.value == refer.refNumber.input) {
            return true;
         }
      }
      return null;
   }
<input list="refNumbers" formControlName="refNb" type="text" name="article" maxlength="8" size="15" required title="8 characters" />

<datalist id="refNumbers">
     <option *ngFor="let ref of listOfArticles">{{ref.refNumber.input}}</option>
</datalist>
从'@angular/core'导入{Component,OnInit};
导入'rxjs/add/operator/switchMap';
从“./management-arbologistique.service”导入{ManagementArbologistiqueService};
从“@angular/router”导入{ActivatedRoute,Params};
从“@angular/forms”导入{FormGroup、FormControl、FormBuilder、FormArray、Validators};
@组成部分({
选择器:“应用程序arbologistique”,
templateUrl:'./arbologistique.component.html',
样式URL:['./arbologistique.component.css']
})
导出类ArbologistiqueComponent实现OnInit{
私有responsetest:字符串;
私有物品列表:数组
私人路径下载:任何;
私有myFormGroup:FormGroup;
fileToUpload:File=null;
private ButtonsSubmitEnabled:boolean=false;
构造函数(公共fb:FormBuilder,私有managementArbo:ManagementArbologistiqueService,私有路由:ActivatedRoute){}
恩戈尼尼特(){
this.myFormGroup=this.fb.group({
itemRows:this.fb.array([this.initItemRows()]))
})
this.myFormGroup.valueChanges.subscribe(x=>this.buttonSubmitEnabled=false);
这是getListBdd();
}
initItemRows(){
返回此.fb.group({
…//其他字段
参考编号:['',[Validators.required,ValidateRefNumber]],
…//其他字段
})
}
addRow(索引:编号){
log(“调用functionAddRow”);
const control=this.myFormGroup.controls['itemRows'];
insert(索引,this.initItemRows());
}
deleteRow(索引:编号){
log(“调用functionDeleteRow”);
const control=this.myFormGroup.controls['itemRows'];
控制。移除(索引);
}
sendForm(){
this.buttonSubmitEnabled=true;
log(“functionExportCalled”);
this.route.params.subscribe((params:params)=>{
let subcure=“导出”;
this.managementArbo.postProducts(子例程,JSON.stringify(this.myFormGroup.value))
.订阅(
res=>{this.reponseTest=res;console.log('reponse:'+res);}
,
err=>console.log(err),
()=>console.log('getProducts done');
});
}
getListBdd(){
this.route.params.subscribe((params:params)=>{
let subcute=“getRefNumber”;
this.managementArbo.getProducts(子例程)
.订阅(
res=>{this.listOfArticles=res;console.log('response:'+res);}
,
err=>console.log(err),
()=>console.log('getProducts done');
});
}
获取refNb(){
返回此.myFormGroup.get('itemRows.refNb');
} 
}
导出函数ValidateRefNumber(控件:AbstractControl){
对于(请参阅ArbologistiqueComponent.listOfArticles){
if(control.value==refere.refNumber.input){
返回true;
}
}
返回null;
}
使用数据列表(component.html)输入:


{{ref.refNumber.input}

我将用一个简单的示例为您提供答案,然后您可以根据需要对其进行转换。
假设我们有以下文章列表:

  articles = [
    {
      id: 1,
      content: "test 123"
    },
    {
      id: 2,
      content: "test 345"
    }
  ];
我们要检查用户是否在输入文本中键入文章的id之一,否则,表单无效

我们有一小段HTML:

<div *ngFor="let article of articles">
    {{article | json}}
</div>
<form [formGroup]="cForm" (submit)="submitForm(cForm.value)" novalidate>
    <input formControlName="article" type="text" name="article" required />
    <input type="submit" value="submit" [disabled]="!cForm.valid">
</form>
因此,我们有一个formGroup,其中包含对required的简单验证,我们的新验证器名为matchValues

export const matchValues = (valuesToCheck: any[]): ValidatorFn => {
  return (control: AbstractControl): { [key: string]: boolean } => {
    const controlValue = control.value;

    let res = valuesToCheck.findIndex(el => el.id === +controlValue);
    console.log(res);
    return res !== -1 ? null : { matched: true };
  };
};
我只是将其包装在一个函数中,该函数接收文章数组,并试图找到一个与输入文本值匹配的文章id。如果我没有找到,我将返回一个对象:

{ matched: true }
这是控件的错误,因此您可以使用与访问required或minlength或任何其他错误相同的“matched”来访问此错误。

我希望它足够清楚,并给你一个很好的开端,以解决你的一点更复杂的问题

--更新--
更清楚地说:

findIndex在数组中搜索与条件匹配的第一个项,并返回该项的索引,如果没有找到,则返回-1。在本例中,我检查了用户输入的值是否与列表中的任何ID匹配。因此,只要我的res不等于-1,这意味着我找到了一个匹配的项,因此验证通过,但如果res==-1,则存在错误,因此我发送了一个新对象,该对象具有匹配的错误名称,以便您以后可以处理它。无论如何,在本例中,我没有找到任何与id匹配的项,因此这是一个错误

--更新2--
您遇到了一些问题,因此我提供了一个工作示例。

我将用一个简单的示例为您提供答案,然后您可以根据需要对其进行转换。
假设我们有以下文章列表:

  articles = [
    {
      id: 1,
      content: "test 123"
    },
    {
      id: 2,
      content: "test 345"
    }
  ];
我们要检查用户是否在输入文本中键入文章的id之一,否则,表单无效

我们有一小段HTML:

<div *ngFor="let article of articles">
    {{article | json}}
</div>
<form [formGroup]="cForm" (submit)="submitForm(cForm.value)" novalidate>
    <input formControlName="article" type="text" name="article" required />
    <input type="submit" value="submit" [disabled]="!cForm.valid">
</form>
因此,我们有一个formGroup,其中包含对required的简单验证,我们的新验证器名为matchValues

export const matchValues = (valuesToCheck: any[]): ValidatorFn => {
  return (control: AbstractControl): { [key: string]: boolean } => {
    const controlValue = control.value;

    let res = valuesToCheck.findIndex(el => el.id === +controlValue);
    console.log(res);
    return res !== -1 ? null : { matched: true };
  };
};
我只是将其包装在一个函数中,该函数接收文章数组,并试图找到一个与输入文本值匹配的文章id。如果我找不到,我会退回一个obje