angularangular-materialcomponents

sub-component does not display the Angular Material design of the containing component


I have a component that uses Angular Material components and its design works great.

But within this component there is another component that is defined as standalone:false and it also uses the same components of Angular Material, but its design simply does not work - that is, it does not cause a compilation error but simply does not refer to the design of Angular Material.

It shouldn't be a problem in imports because in the wrapping component the design works great.

I tried to add encapsulation: ViewEncapsulation.None to the external component And it didn't help

Here is the attached code:

import { Component, OnInit, ViewChild, AfterViewInit, OnDestroy, ViewEncapsulation } from '@angular/core';
import { Customer } from '../../Models/Customer';
import { customerService } from '../../services/costumer.service';
import { MaterialModule } from '../../material/material.module';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { CommonModule } from '@angular/common';
import { MatTableDataSource } from '@angular/material/table';
import { MatDialog } from '@angular/material/dialog';
import { MatDialogRef } from '@angular/material/dialog';
import { MatSort } from '@angular/material/sort';
import { MatPaginator } from '@angular/material/paginator';
@Component({
  selector: 'customer-list',
  standalone: true,
  imports: [MaterialModule, CommonModule],
  templateUrl: './customer-list.component.html',
  styleUrls: ['./customer-list.component.scss'],
  encapsulation: ViewEncapsulation.None,
})
export class CustomerListComponent implements OnInit, OnDestroy {
  displayedColumns = ['first_Name', 'last_Name', 'address', 'phone', 'email', ' '];
  dataSource: MatTableDataSource<Customer> = new MatTableDataSource<Customer>();
  private customersSubscription?: Subscription;

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

  constructor(private customerService: customerService, private router: Router, public dialog: MatDialog) {}

  ngOnInit(): void {
    this.loadCustomers();
  }

  loadCustomers(): void {
    this.customersSubscription = this.customerService.customers$.subscribe({
      next: customers => {
        this.dataSource.data = customers;
        this.dataSource.sort = this.sort;
        this.dataSource.paginator = this.paginator;
      },
      error: error => {
        console.error('Error loading customers:', error);
      }
    });
  }

  ngOnDestroy(): void {
    if (this.customersSubscription) {
      this.customersSubscription.unsubscribe();
    }
  }

  ngAfterViewInit(): void {
    this.dataSource.sort = this.sort;
    this.dataSource.paginator = this.paginator;
  }

  applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    this.dataSource.filter = filterValue.trim().toLowerCase();

    if (this.dataSource.paginator) {
      this.dataSource.paginator.firstPage();
    }
  }

  addCustomer(): void {
    this.router.navigate(['/customer-details', -1]);
  }

  editCustomer(selected: Customer): void {
    this.router.navigate(['/customer-details', selected.id]);
  }

  deleteCustomer(customer: Customer): void {
    const dialogRef = this.dialog.open(ConfirmDialog);

    dialogRef.afterClosed().subscribe(result => {
      if (result) {
        this.customerService.deleteCustomer(customer.id!).subscribe({
          next: () => {
            console.log('Customer deleted successfully');
          },
          error: error => {
            console.error('Error deleting customer:', error);
          }
        });
      }
    });
  }
}

/*-------------------------confirm-dialog-component----------------------------------------- */

@Component({
  selector: 'confirm-dialog',
  template: `
    <div >
      <h1 mat-dialog-title>Confirm Deletion</h1>
      <div mat-dialog-content>Are you sure you want to delete this client?</div>
      <div mat-dialog-actions>
        <button mat-button (click)="onNoClick()" >No</button>
        <button mat-button color="primary" (click)="onYesClick()" cdkFocusInitial>Yes</button>
      </div>
    </div>
  `
})
export class ConfirmDialog  {
  constructor(public dialogRef: MatDialogRef<ConfirmDialog>) {}

  onNoClick(): void {
    this.dialogRef.close(false);
  }

  onYesClick(): void {
    this.dialogRef.close(true);
  }
}

I would really appreciate any hint as to what the problem could be


Solution

  • The dialog is opened in the root of the application and has no relation to the component that opens it, styles wise and import. So it's better for the dialog component to have its own imports and styles. We can also set it as standalone, since it works independently of any other component.

    @Component({
      selector: 'confirm-dialog',
      standalone: true,
      styles: [``],
      imports: [MaterialModule, CommonModule],
      template: `
        <div >
          <h1 mat-dialog-title>Confirm Deletion</h1>
          <div mat-dialog-content>Are you sure you want to delete this client?</div>
          <div mat-dialog-actions>
            <button mat-button (click)="onNoClick()" >No</button>
            <button mat-button color="primary" (click)="onYesClick()" cdkFocusInitial>Yes</button>
          </div>
        </div>
      `
    })
    export class ConfirmDialog  {
      constructor(public dialogRef: MatDialogRef<ConfirmDialog>) {}
    
      onNoClick(): void {
        this.dialogRef.close(false);
      }
    
      onYesClick(): void {
        this.dialogRef.close(true);
      }
    }