表Angular Material中的表格的Angular 6 Validator问题

时间:2018-12-12 09:57:24

标签: angular angular-material angular-reactive-forms formarray

我正在使用Angular 6构建应用程序,但我对反应式表单有疑问。我正在学习Angular。我有一个表格的所有行的表格,其中有一个要验证的输入是PRODUCT_QUANTITY。输入的数字发生更改时,它将提交表单以使用新值更新表。问题是当我专注于元素并且不更改值时,将为表的所有行激活验证程序错误。我希望仅在未设置数量的情况下对相关行进行激活。对不起,如果我的代码不完美。 您能帮我解决这个问题吗?谢谢

这是代码:

tables.component.html

<mat-form-field>
    <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
<ng-container>
    <mat-form-field>
        <mat-select placeholder="Filter par type de produit"
                    multiple (selectionChange)="displayData($event.value)"
                    [(ngModel)]="selectedProductsId"
                    #productIdSelect="ngModel">
            <button
                    mat-raised-button
                    class="mat-warn fill text-sm"
                    (click)="emptyFilter(productIdSelect,ids)">
                Supprimer filtre
            </button>
            <mat-option *ngFor="let product of productListType" [value]="product.PRODUCTS_id">{{product.PRODUCTS_title}}</mat-option>
        </mat-select>
    </mat-form-field>
</ng-container>
<div class="mat-elevation-z8">
    <form [formGroup]="form" (submit)="addProductToList()">
        <table mat-table [dataSource]="dataSource" matSort>


            <ng-container matColumnDef="PRODUCT_name">
                <th mat-header-cell *matHeaderCellDef mat-sort-header> Nom du produit</th>
                <td mat-cell *matCellDef="let row"> {{row.PRODUCT_name}} </td>
            </ng-container>

            <ng-container matColumnDef="PRODUIT_TYPE">
                <th mat-header-cell *matHeaderCellDef mat-sort-header> Type de produit</th>
                <td mat-cell *matCellDef="let row"> {{row.PRODUIT_TYPE}}</td>
            </ng-container>

            <ng-container matColumnDef="PRODUCT_QUANTITY">
                <th mat-header-cell *matHeaderCellDef mat-sort-header> Quantité</th>
                <td mat-cell *matCellDef="let row">
                    <mat-form-field style="width: 50%">
                        <input (change)="setIdProduct(row.PRODUCT_id)" formControlName="quantity" matInput min="0" type="number" placeholder="Quantité" value="{{row.PRODUCT_QUANTITY}}">
                    </mat-form-field>
                </td>
            </ng-container>

            <ng-container matColumnDef="PRODUCT_COMMENT">
                <th mat-header-cell *matHeaderCellDef mat-sort-header>Commentaire</th>
                <td mat-cell *matCellDef="let row">
                    <mat-form-field style="width: 60%">
                        <textarea (change)="setIdProduct(row.PRODUCT_id)" formControlName="remark" matInput placeholder="Ajouter un commentaire"
                                  value="{{row.PRODUCT_COMMENT}}"></textarea>
                    </mat-form-field>
                </td>
            </ng-container>

            <ng-container matColumnDef="VALIDATE">
                <th style="display: none" mat-header-cell *matHeaderCellDef mat-sort-header>Ajouter un produit</th>
                <td mat-cell *matCellDef="let row">
                    <button id="submitForProduct" style="display: none;" mat-raised-button color="primary" type="submit">Ajouter à ma liste de
                        course
                    </button>
                </td>
            </ng-container>

            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
            <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
        </table>

    </form>

    <mat-paginator [pageSize]="10" [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
</div>

tables.component.ts

import {Component, OnInit, ViewChild} from '@angular/core';
import {MatPaginator, MatSnackBar, MatSort, MatTableDataSource} from '@angular/material';
import {ProductService} from '../../services/product.service';
import {Product} from '../../models/product';
import {ProductType} from '../../models/producttype';
import {FormBuilder, FormGroup, NgModel, Validators} from '@angular/forms';
import {Subscription} from 'rxjs';
import {forEach} from 'async';

@Component({
    selector: 'app-tables',
    templateUrl: './tables.component.html',
    styleUrls: ['./tables.component.scss']
})
export class TablesComponent implements OnInit {
    displayedColumns = ['PRODUCT_name', 'PRODUIT_TYPE', 'PRODUCT_QUANTITY', 'PRODUCT_COMMENT', 'VALIDATE'];
    dataSource: MatTableDataSource<Product>;
    productListType: ProductType[];
    productListItem: Product[] = [];
    filteredArray: Product[] = [];
    selectedProductsId: ProductType[];
    ids: any[] = [];
    form: FormGroup;
    response: Subscription;
    idProduct: number;


    @ViewChild(MatPaginator) paginator: MatPaginator;
    @ViewChild(MatSort) sort: MatSort;

    constructor(private productProvider: ProductService, private addProduct: FormBuilder, private snackBar: MatSnackBar) {
        console.log(this.productListItem);
    }

    ngOnInit() {
        this.productProvider.getAllProducts().subscribe(
            r => {
                this.productListType = r['products'] as ProductType[];
                this.productListType.forEach(product => {
                    this.ids.push(product.PRODUCTS_id);
                    product.PRODUCTS_products.forEach(productItem => {
                        this.productListItem.push(new Product(
                            productItem.PRODUCT_id,
                            productItem.PRODUCT_name,
                            productItem.PRODUCT_unit,
                            product.PRODUCTS_title,
                            product.PRODUCTS_id,
                            0,
                            ''));
                    });
                });
                this.productProvider.getProductsHousehold(1).subscribe(
                    result => {
                        this.productListItem.map(productItem => {
                            result.products.map(productItemR => {
                                if (productItemR.PRODUCTS_LIST_id_prod === productItem.PRODUCT_id) {
                                    console.log(productItemR.PRODUCTS_LIST_QUANTITY);
                                    productItem.PRODUCT_QUANTITY = productItemR.PRODUCTS_LIST_quantity;
                                    productItem.PRODUCT_COMMENT = productItemR.PRODUCTS_LIST_remark;
                                }
                            });
                        });
                        console.log(this.productListItem)
                    });
                this.dataSource = new MatTableDataSource<Product>(this.productListItem);
                this.dataSource.sort = this.sort;
                this.dataSource.paginator = this.paginator;
            });
        this.form = this.addProduct.group({
            quantity: ['', [Validators.required]],
            remark: ['']
        });
    }

// filter the list of products
    applyFilter(filterValue: string) {
        filterValue = filterValue.trim(); // Remove whitespace
        filterValue = filterValue.toLowerCase(); // Datasource defaults to lowercase matches
        this.dataSource.filter = filterValue;
        if (this.dataSource.paginator) {
            this.dataSource.paginator.firstPage();
        }
    }

//Display data when filter changed    
    displayData(event) {
        let array: any;
        array = event;
        if (array.length === 0) {
            array = this.ids;
        }
        console.log(array);
        this.filteredArray = [];
        this.productListType.forEach(product => {
            array.forEach(productId => {
                if (product.PRODUCTS_id === productId) {
                    product.PRODUCTS_products.forEach(pro => {
                        this.filteredArray.push(new Product(
                            pro.PRODUCT_id,
                            pro.PRODUCT_name,
                            pro.PRODUCT_unit,
                            product.PRODUCTS_title,
                            product.PRODUCTS_id,
                            pro.PRODUCT_QUANTITY,
                            pro.PRODUCT_COMMENT));
                    });
                }
            });
        });
        this.dataSource = new MatTableDataSource<Product>(this.filteredArray);
        this.dataSource.sort = this.sort;
        this.dataSource.paginator = this.paginator;
    }
//empty the filter
    emptyFilter(select
                    :
                    NgModel, values
    ) {
        select.update.emit([]);
        this.displayData([]);
    }

//set Id Product and trigger event submit
    setIdProduct(PRODUCT_id
                     :
                     number
    ) {
        this.idProduct = PRODUCT_id;
        console.log(this.idProduct);
        document.getElementById('submitForProduct').click();
    }

// function called when the form is submitted    
    addProductToList() {
        if (this.form.invalid || this.idProduct < 0) {
            this.snackBar.open('Veuillez renseigner tous les champs', '', {
                duration: 2000
            });
            return;
        }
        const quantity = this.form.controls.quantity.value;
        const remark = this.form.controls.remark.value;
        this.response = this.productProvider.addProductToList(this.idProduct, 1, quantity, remark).subscribe(
            result => {
                if (result === true) {
                    this.snackBar.open('Le produit a bien été ajouté à la liste', '', {
                        duration: 2000
                    });
                } else {
                    this.snackBar.open('Produit non ajouté à la liste', '', {
                        duration: 2000
                    });
                }
            });
    }
}

0 个答案:

没有答案