英文:
Reactive Forms: Multiselect
问题
我对响应式表单非常陌生,所以我不知道如何实现我想要的功能。
我有一个Observable,其中我获取以下数据:
AllUsers: [
    {
        User_ID: "xxxA",
        User_Name: "AAAA"
    },
    {
        User_ID: "xxxB",
        User_Name: "BBBB"
    },
    {
        User_ID: "xxxC",
        User_Name: "CCCC"
    }
]
ProductsBoughtBy: [
    {
        Product: {
            Product_ID: "xaxa",
            Product_Name: "Product 1",
            Version: 2
        },
        UsersBought: [
            {
                User_ID: "xxxA",
                User_Name: "AAAA"
            },
            {
                User_ID: "xxxB",
                User_Name: "BBBB"
            }
        ]
    },
    {
        Product: {
            Product_ID: "xbxb",
            Product_Name: "Product 2",
            Version: 4
        },
        UsersBought: [
            {
                User_ID: "xxxA",
                User_Name: "AAAA"
            },
            {
                User_ID: "xxxC",
                User_Name: "CCCC"
            }
        ]
    }
]
在HTML中,我使用ngx-table显示一个具有3列的表格。第一列用于产品名称,第二列用于产品版本,第三列是来自Angular Material的多选框,其中列出了所有用户,并默认选中了ProductsBoughtBy中的用户。
但我不明白如何创建我的FormsArray,或者我是否需要FormsGroup。以及如何将它绑定到HTML的mat-select元素上。
提前感谢。
英文:
I am very new to reactive forms so I do not have a clue how to do what I want.
I have an Observable where I get the following data:
AllUsers: [
	{
		User_ID: "xxxA",
		User_Name: "AAAA"
	},
	{
		User_ID: "xxxB",
		User_Name: "BBBB"
	},
	{
		User_ID: "xxxC",
		User_Name: "CCCC"
	}
]
ProductsBoughtBy: [
	{
		Product: {
			Product_ID: "xaxa",
			Product_Name: "Product 1",
			Version: 2
		},
		UsersBought: [
			{
				User_ID: "xxxA",
				User_Name: "AAAA"
			},
			{
				User_ID: "xxxB",
				User_Name: "BBBB"
			}
		]
	},
	{
		Product: {
			Product_ID: "xbxb",
			Product_Name: "Product 2",
			Version: 4
		},
		UsersBought: [
			{
				User_ID: "xxxA",
				User_Name: "AAAA"
			},
			{
				User_ID: "xxxC",
				User_Name: "CCCC"
			}
		]
	}
]
In the html I use ngx-table to show a table with 3 Column. The First one is used for Product Name, the second for Product version and the third for a multiselect from angular material, where all users are listed and the users from the ProductsBoughtBy are checked per default.
But I do not understand how to create my ?FormsArray? or do I need the FormsGroup. And how to bind it to the html mat-select.
Thanks in advance.
答案1
得分: 1
首先,在您的组件中导入必要的模块
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
在您的组件类中创建一个 FormGroup 和 FormArray
export class YourComponent implements OnInit {
  form: FormGroup;
  usersArray: FormArray;
  constructor(private formBuilder: FormBuilder) {}
  ngOnInit() {
    this.form = this.formBuilder.group({
      products: this.formBuilder.array([])
    });
    this.usersArray = this.formBuilder.array([]);
    this.form.addControl('users', this.usersArray);
  }
}
现在使用您的数据填充表单
data$.subscribe(data => {
  const productsArray = this.form.get('products') as FormArray;
  data.ProductsBoughtBy.forEach(product => {
    const productGroup = this.formBuilder.group({
      name: product.Product.Product_Name,
      version: product.Product.Version,
      users: this.formBuilder.array([])
    });
    product.UsersBought.forEach(user => {
      const userGroup = this.formBuilder.group({
        id: user.User_ID,
        name: user.User_Name
      });
      (productGroup.get('users') as FormArray).push(userGroup);
    });
    productsArray.push(productGroup);
  });
});
现在使用 formGroup 指令和 formArrayName 指令将表单控件绑定到您的 HTML 模板
<form [formGroup]="form">
  <div formArrayName="products">
    <div *ngFor="let product of form.get('products').controls; let i = index" [formGroupName]="i">
      <div>{{ product.get('name').value }}</div>
      <div>{{ product.get('version').value }}</div>
      <mat-form-field appearance="fill">
        <mat-label>Users</mat-label>
        <mat-select [formControlName]="'users'" multiple>
          <mat-option *ngFor="let user of product.get('users').controls; let j = index" [value]="user.get('id').value">
            {{ user.get('name').value }}
          </mat-option>
        </mat-select>
      </mat-form-field>
    </div>
  </div>
</form>
希望对您有所帮助
英文:
First, import the necessary modules in your component
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
Create a FormGroup and FormArray in your component class
export class YourComponent implements OnInit {
  form: FormGroup;
  usersArray: FormArray;
  constructor(private formBuilder: FormBuilder) {}
  ngOnInit() {
    this.form = this.formBuilder.group({
      products: this.formBuilder.array([])
    });
    this.usersArray = this.formBuilder.array([]);
    this.form.addControl('users', this.usersArray);
  }
}
now populate the form with your data
data$.subscribe(data => {
  const productsArray = this.form.get('products') as FormArray;
  data.ProductsBoughtBy.forEach(product => {
    const productGroup = this.formBuilder.group({
      name: product.Product.Product_Name,
      version: product.Product.Version,
      users: this.formBuilder.array([])
    });
    product.UsersBought.forEach(user => {
      const userGroup = this.formBuilder.group({
        id: user.User_ID,
        name: user.User_Name
      });
      (productGroup.get('users') as FormArray).push(userGroup);
    });
    productsArray.push(productGroup);
  });
});
Now bind the form controls to your HTML template using the formGroup directive and the formArrayName directive
<form [formGroup]="form">
  <div formArrayName="products">
    <div *ngFor="let product of form.get('products').controls; let i = index" [formGroupName]="i">
      <div>{{ product.get('name').value }}</div>
      <div>{{ product.get('version').value }}</div>
      <mat-form-field appearance="fill">
        <mat-label>Users</mat-label>
        <mat-select [formControlName]="'users'" multiple>
          <mat-option *ngFor="let user of product.get('users').controls; let j = index" [value]="user.get('id').value">
            {{ user.get('name').value }}
          </mat-option>
        </mat-select>
      </mat-form-field>
    </div>
  </div>
</form>
hope it's helpful
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论