Проблема с угловым валидатором 6 для формы в таблице угловой материал - PullRequest
0 голосов
/ 12 декабря 2018

Я создаю приложение с 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
                    });
                }
            });
    }
}
...