Angular 10-将FormControl数组值转换为以逗号分隔的字符串 我得到的是:数组值我想要的是:字符串值用逗号分隔,没有[]

问题描述

编辑1:

修改了问题以明确我的需求。

我有一个 var index = 0; // add parent partial view function AddPost(element) { var action = '@Url.Action("AddPost_PV","Blog")'; $.post(action) .done(function (partialView) { index++; $("#parent_pv_container").append("<h4>Parent Partial View " + index + "</h4><hr />"); $('#parent_pv_container').append(partialView); }); } var childindex = 0; //add children partial view. function AddBlog(element) { var action = '@Url.Action("AddBlog_PV","Blog")'; $.post(action) .done(function (partialView) { childindex++; $(element).parent().find("#child_pv_container").append("<h4>Child Partial View " + childindex + "</h4><hr />"); $(element).parent().find("#child_pv_container").append(partialView); }); } ,其中包含FormGroup

在这FormControl中,有一个接收数组值。

我正在寻找的是是否存在一种解决方案,以使FormControl可以接收数组值,而不是以逗号分隔的字符串值(不带括号FormControl)来接收值。

我得到的是:(数组值)

Array Values

我想要的是:(字符串值用逗号分隔,没有[]

enter image description here

前叉链接Here

  • 预先感谢您的帮助

原始问题:

我想将从brackets[]接收到的数据转换为带逗号的字符串。

我设法在Console.log中做到了这一点,但是我不知道如何将转换后的数据发送到FormArray

我的TS文件

FormGroup

我的 accessoire: string; this.demandeDevis = this.formBuilder.group({ accessoires: new FormArray([]),accessoire: this.accessoire,}); onCheckBoxChange(event) { const checkAcs: FormArray = this.demandeDevis.get( 'accessoires' ) as FormArray; if (event.target.checked) { checkAcs.push(new FormControl(event.target.value)); console.log(checkAcs.value.toString()); this.accessoire = checkAcs.value.toString(); } else { let i: number = 0; checkAcs.controls.forEach((item: FormControl) => { if (item.value == event.target.value) { checkAcs.removeAt(i); return; } i++; }); } }

HTML

按照这些步骤操作时,在“ Accessoire”上得到 <ul class="list-group list-group-flush"> <li class="list-group-item p-3"> Ventilateur cabine <label class="switch"> <input type="checkBox" value="Ventilateur cabine" class="primary" (change)="onCheckBoxChange($event)" /> <span class="slider"></span> </label> </li> <li class="list-group-item p-3"> Manoeuvre pompier <label class="switch"> <input type="checkBox" class="primary" value="Manoeuvre pompier" (change)="onCheckBoxChange($event)" /> <span class="slider"></span> </label> </li> <li class="list-group-item p-3"> Afficheur à tous les étages <label class="switch"> <input type="checkBox" class="primary" value="Afficheur à tous les étages" (change)="onCheckBoxChange($event)" /> <span class="slider"></span> </label> </li> <li class="list-group-item p-3"> Gong <label class="switch"> <input type="checkBox" class="primary" value="Gong" (change)="onCheckBoxChange($event)" /> <span class="slider"></span> </label> </li> <li class="list-group-item p-3"> Système de secours automatique <label class="switch"> <input type="checkBox" class="primary" value="Système de secours automatique" (change)="onCheckBoxChange($event)" /> <span class="slider"></span> </label> </li> </ul> ,在“ Accessoires”上得到数组值。

我正在寻找的是获取从复选框列表中选择的值,并将其转换为带逗号的字符串。我不想以数组形式发送它们。

提前感谢您的解决方案。

编辑1:

我使用了 @akash 解决方案的第一个选项,它正在运行。我有一点问题。当我得到在null上选择的值时,我想将其发送到input ...我得到带括号的数组形式...我想要的是带逗号的字符串形式。这是我的问题的链接https://stackblitz.com/edit/reactive-form-string-values

解决方法

<mat-select 
      [value]="toppings.value?toppings?.value.split(','):null" 
      (selectionChange)="toppings.setValue($event.value.join(','))"
       multiple>
...
</mat-select>

即使您没有输入,也要记住FormControl存在。好吧,您需要重写所有代码以接收字符串,例如this forked stackblitz

,

更新2

要从数据库值填充表单,只需初始化控件toppings,如下所示(请参见this fork)-

toppingsValue: string = 'Extra cheese,Mushroom';
this.demandeDevis = this.formBuilder.group({
      toppings: [this.toppingsValue.split(',').map(a => a.trim())]
});

更新1

我想我误解了您要实现的目标。请了解角度FormGroup的工作方式。 FormGroup具有控件字段,这是您作为下面的对象传递的内容。该对象是一个键值,其中key是控件名称(浇头),value是控件(例如FormControl,FormArray或FormGroup)-

this.demandeDevis = this.formBuilder.group({
      toppings: this.toppings 
});

因此,当您执行this.demandeDevis.value时,将在相应控件中获得具有相同键(顶部)和值的对象。您可以使用以下代码来获取toppings的逗号分隔值。不确定这是否是您要查找的内容,因为这很明显(请参见this fork)-

validateForm(){
    const toppingsValue = this.demandeDevis.controls['toppings'].value;
    console.log(toppingsValue.toString()); 
}

原始答案

如果您对用户界面的外观持不同态度,请使用angular material

选项1

使用mat-select组件。在下面的示例中,您无需处理选项的选择/取消选择。请参阅this example on StackBlitz-

<mat-form-field appearance="fill">
  <mat-label>Toppings</mat-label>
  <mat-select [formControl]="toppings" multiple>
    <mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option>
  </mat-select>
</mat-form-field>

<div>
{{toppings.value}}
</div>

选项2

如果您不想使用下拉菜单,请使用mat-selection-list,请参见this example。下面的示例使用对mat-selection-list的引用来获取组件中选定选项的列表-

<mat-selection-list #shoes (selectionChange)=selectionChange()>
  <mat-list-option [value]="shoe" *ngFor="let shoe of typesOfShoes">
    {{shoe}}
  </mat-list-option>
</mat-selection-list>
{{selectedValuesG}}
,

您可以执行类似here

的操作
 ngOnInit() {
  this.initDemandeDevis();
  this.toppings.valueChanges.subscribe(value => {
    this.demandeDevis.patchValue({
      toppingsToString: value.length > 0 ? value.join(",") : ""
    });
  });
 }

 initDemandeDevis() {
   this.demandeDevis = this.formBuilder.group({
     toppingsToString: "",accessoires: null
   });
 }

您必须将其拆分回以填充浇头阵列,但是我不确定是否需要它。

,

我的解决方案是在需要时使用Observable并转换数据。

// We define an Observable list of toppings
allToppings$: Observable<string[]> = of (['Extra cheese','Mushroom','Onion','Pepperoni','Sausage','Tomato']);

// We define our FormGroup
demandeDevis: FormGroup = this.formBuilder.group({
  toppings: [[]]
});

// Lets assume an initial topping in the form of string. Since MatSelect returns array,we will convert this to array and assign it to toppings selected
initialToppings$: Observable<string> = of('Onion,Pepperoni,Tomato'); 
initialToppingListArray$: Observable<string[]> = this.initialToppings$.pipe(
  map(toppingList => toppingList.split(',')),tap(toppings => this.toppings.patchValue(toppings))
);

// Next we define toppings and toppingsValue to extract toppings and toppings as a string from the form group
get toppings(): FormControl {
  return this.demandeDevis.get('toppings') as FormControl
};

get toppingsValue(): string {
  return this.toppings.value.join(',')
}

// Finally I will combine allToppings$ and initialToppingListArray$ to use one async pipe in the HTML
v$ = forkJoin([this.allToppings$,this.initialToppingListArray$]).pipe(
  map(([allToppings]) => ({ allToppings}))
)

在HTML

<form [formGroup]="demandeDevis" *ngIf='v$ | async as v'>
<mat-form-field appearance="fill">
  <mat-label>Toppings</mat-label>
  <mat-select formControlName="toppings" multiple>
    <mat-option *ngFor="let topping of v.allToppings" [value]="topping">{{topping}}</mat-option>
  </mat-select>
</mat-form-field>

<button (click)="validateForm()" >
  Validate (console.log) 
  </button>
</form>


TOPPINGS VALUE: {{ toppingsValue }}

现在,您可以使用toppingsValue

作为字符串来访问列表。

See Sample on Stackblit

,

您将需要创建一个自定义控件

See Working Solution

app-string-select.ts

import { Component,forwardRef,OnInit } from "@angular/core";
import { ControlValueAccessor,NG_VALUE_ACCESSOR } from "@angular/forms";
import { Observable,of } from "rxjs";

@Component({
  selector: "app-string-select",templateUrl: "./string-select.component.html",styleUrls: ["./string-select.component.css"],providers: [
    {
      provide: NG_VALUE_ACCESSOR,useExisting: forwardRef(() => StringSelectComponent),multi: true
    }
  ]
})
export class StringSelectComponent implements ControlValueAccessor {
  value: string[] = [];
  allToppings$: Observable<string[]> = of([
    "Extra cheese","Mushroom","Onion","Pepperoni","Sausage","Tomato"
  ]);
  onChange: any = () => {};
  onTouched: any = () => {};
  constructor() {}
  writeValue(value: string): void {
    this.value = value.split(",");
  }
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }
  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }
  emitChange() {
    this.onChange(this.value.join(","));
  }
}

app-string-select.html

<mat-form-field appearance="fill">
  <mat-label>Toppings</mat-label>
  <mat-select [(ngModel)]="value" (ngModelChange)='emitChange()' multiple>
    <mat-option *ngFor="let topping of allToppings$ | async" [value]="topping">{{topping}}</mat-option>
  </mat-select>
</mat-form-field>

select-multi-example.ts

import {ChangeDetectionStrategy,Component} from '@angular/core';
import {FormControl,FormGroup,FormBuilder} from '@angular/forms';
import {Observable,of } from 'rxjs';
import {tap } from 'rxjs/operators';

/** @title Select with multiple selection */
@Component({
  selector: 'select-multiple-example',templateUrl: 'select-multiple-example.html',changeDetection: ChangeDetectionStrategy.OnPush
})
export class SelectMultipleExample {

  demandeDevis: FormGroup = this.formBuilder.group({ toppings: ['']});

  initialToppings$: Observable<string> = of('Onion,Tomato').pipe(
    tap(toppings => this.toppings.patchValue(toppings))
  )

  get toppings(): FormControl {
    return this.demandeDevis.get('toppings') as FormControl
  };

  constructor(private formBuilder: FormBuilder) {}

  validateForm(){
    const valuesForm = this.toppings.value;
    console.log(valuesForm); 
  }
}

select-multiple-example.html

<form [formGroup]="demandeDevis" *ngIf="initialToppings$ | async">
<app-string-select formControlName='toppings'></app-string-select>

<div>
   <button (click)="validateForm()" >
    Validate
  </button>
</div>
</form>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...