【问题标题】:angular2 material table hide columnangular2材质表隐藏栏
【发布时间】:2022-03-04 17:56:41
【问题描述】:

我有以下angular2材质表

<mat-table #table [dataSource]="dataSource" >

        <!--- Note that these columns can be defined in any order.
              The actual rendered columns are set as a property on the row definition" -->

        <!-- Position Column -->
        <ng-container matColumnDef="selected">
            <mat-header-cell *matHeaderCellDef>
                <mat-checkbox [(ngModel)]="selectAll"></mat-checkbox>
            </mat-header-cell>
            <mat-cell *matCellDef="let element">
                <mat-checkbox [(ngModel)]="element.selected" [checked]="selectAll"></mat-checkbox>
            </mat-cell>
        </ng-container>

        <ng-container matColumnDef="id">
            <mat-header-cell *matHeaderCellDef> Id</mat-header-cell>
            <mat-cell *matCellDef="let element"> {{element.id}}</mat-cell>
        </ng-container>

        <ng-container matColumnDef="requested_status">
            <mat-header-cell *matHeaderCellDef> Status</mat-header-cell>
            <mat-cell *matCellDef="let element"> {{element.requested_status}}</mat-cell>
        </ng-container>
        ......

我需要通过一些布尔条件隐藏表格中的一列。 是否可以不更改组件中的列映射?

displayedColumns = ['selected', 'id', ...];

我尝试使用*ngIf,但它不起作用。该怎么做?

【问题讨论】:

  • 根据需要修改显示的列

标签: angular angular-material


【解决方案1】:

不需要任何指令。

随便用

[隐藏] 它会起作用的 例如:[隐藏] =“显示”在 html 和 在 ts 文件中将 show 设置为布尔值。

我的html代码:

<ng-container matColumnDef="department" >
  <mat-header-cell [hidden]="show" *matHeaderCellDef> 
    Department 
  </mat-header-cell>
  <mat-cell [hidden]="show" *matCellDef="let element">
    {{element.department}}
  </mat-cell>
</ng-container>

【讨论】:

    【解决方案2】:

    这样做的角度方法是update the columns passed to your row template

    HTML:

    <mat-row *matRowDef="let row; columns: getDisplayedColumns();"></mat-row>
    

    TS:

    const columnDefinitions = [
      { def: 'col1', showMobile: true },
      { def: 'col2', showMobile: false },
    ];
    
    getDisplayedColumns(): string[] {
      const isMobile = this.currentDisplay === 'mobile';
      return this.columnDefinitions
        .filter(cd => !isMobile || cd.showMobile)
        .map(cd => cd.def);
    }
    

    【讨论】:

    • 这种方法的问题是,如果您使用 mat-menu 复选框,则每次单击检查时对话框都会关闭。只有 display = none 解决了问题(使用 event.stopPropagation())。
    • 另一个问题是getDisplayedColumns() 将在每次更改检测时触发(这种情况经常发生)。
    • 这是一个简单的例子来说明这一点,你们制作的两个 cmets 都有简单的修复,比如不调用 getDisplayedColumns() 而是一次填充的常量,或者当 x 事件发生时。您的观点不会使这种方法无效,只需调整您的实现即可。
    • 这不起作用。在呈现列名的初始数组 (displayedColumns) 后,Mat 表无法动态更新列。例如,如果您正在获取一些数据,并且在初始页面加载时displayedColumns = ['a', 'b'],那么它将显示ab 作为列。当获取的数据解析并且您现在想要将列动态更改为displayedColumns=['a', 'b', 'c'],从而添加列c,这将不起作用。这些列不会动态更新,或者至少不会一致。这是个问题。
    • 这确实有效,在你的实现上工作,而不是复制粘贴一个最小的工作示例。
    【解决方案3】:

    在要隐藏的列中添加:

    [style.display]="'none'"
    

    您应该同时添加 mat-h​​eather-cell 和 mat-cell。

    【讨论】:

      【解决方案4】:

      我正在使用 Angular Flex 响应式 API (https://github.com/angular/flex-layout/wiki/Responsive-API)。 示例:

           <ng-container matColumnDef="date">
              <th
                *matHeaderCellDef
                mat-header-cell
                mat-sort-header
                fxShow
                fxHide.lt-sm
              >
                Data
              </th>
              <td *matCellDef="let element" mat-cell fxShow fxHide.lt-sm>
                {{ element.date | date: "dd/MM/yyyy" }}
              </td>
              <td *matFooterCellDef mat-footer-cell fxShow fxHide.lt-sm>Total</td>
            </ng-container>
      

      在这种情况下,将隐藏在屏幕小于小(lt-sm)。

      【讨论】:

        【解决方案5】:

        唯一可能的解决方案似乎是更改组件类中的显示列

        displayedColumns = ['selected', 'id', ...];
        

        【讨论】:

          【解决方案6】:

          最后我找到了一种在不更改列映射的情况下隐藏列的方法。 我们需要创建一个属性指令,通过这个指令我们可以设置一个元素的显示属性。

          ShowColumnDirective:

          import {Component, Directive, ElementRef, Input, AfterViewInit} from '@angular/core';
          @Directive({ 
               selector: '[showCoulmn]' 
          })
          export class ShowColumnDirective implements AfterViewInit{
              @Input() showInput: string;
              constructor(private elRef: ElementRef) { 
              }
              ngAfterViewInit(): void {
              this.elRef.nativeElement.style.display = this.showInput;
              }
          }
          

          在 AppModule 或任何其他模块中声明此指令:

          import {TableBasicExample} from './table-basic-example';
          import {ShowColumnDirective} from './table-basic-example';
          @NgModule({
          
            imports: [
              ..........
            ],
          
            declarations: [TableBasicExample, ShowColumnDirective],
            bootstrap: [TableBasicExample],
            providers: []
          })
          export class AppModule {}
          

          现在我们可以在表格的 html 组件中使用指令:

          <ng-container matColumnDef="position">
            <mat-header-cell showCoulmn showInput="none" *matHeaderCellDef> No. </mat-header-cell>
            <mat-cell showCoulmn showInput="none"    *matCellDef="let element"> {{element.position}} </mat-cell>
          </ng-container>
          

          这是工作模板:https://plnkr.co/edit/Woyrb9Yx8b9KU3hv4RsZ?p=preview

          【讨论】:

            【解决方案7】:

            如果您要通过某些可变条件隐藏一行,我建议以下方式:

            // css
            .hidden-row {
              display: none;
            }
            
            // html
            <ng-container matColumnDef="importDate">
              <mat-header-cell *matHeaderCellDef [ngClass]="showColumn()">
                  Date
              </mat-header-cell>
              <mat-cell *matCellDef="let element" [ngClass]="showColumn()">
                  {{element?.importDate}}
              </mat-cell>
            </ng-container>
            
            // ts
            showColumn(): string {
              return this.someService.hasAccess() ? null : 'hidden-row';
            }
            

            【讨论】:

              【解决方案8】:

              @John Smith 提出的解决方案对我不起作用。相反,我使用了这个调整:

               // css
               .hidden-item {
                 display: none;
               }
              
               // html
               <ng-container matColumnDef="importDate">
                 <mat-header-cell *matHeaderCellDef [ngClass]="{'hidden-item': showColumn()}"> Date
                 </mat-header-cell>
                 <mat-cell *matCellDef="let element" [ngClass]="{'hidden-item': showColumn()}"> {{element?.importDate}}
                 </mat-cell>
               </ng-container>
              
               // ts
               showColumn(): boolean {
                 return this.someService.hasAccess();
               }
              

              【讨论】:

              • 不要在 Angular 模板中使用函数。它会在每个更改检测周期触发重新渲染
              • 这有问题吗?
              【解决方案9】:

              这有可能在这个错误的问题中解释:https://github.com/angular/material2/issues/8944

              查看:

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

              类:

              displayedColumns = ['tab1', 'tab2', 'tab3'];
              

              但在构造函数中:

              if (this.removeOneColumn) this.displayedColumns = ['tab1', 'tab3'];
              

              【讨论】:

                【解决方案10】:

                我遇到了同样的问题,用户可以通过复选框显示或隐藏列。我通过管道解决了我的问题,如下所示:

                @Component({
                  selector: "app-dynamic-table",
                  template: `
                    <mat-checkbox *ngFor="let column of columns" [(ngModel)]="column.show">{{column.name | titlecase}}</mat-checkbox>
                    <mat-table #table [dataSource]="dataSource">
                      ....
                      <mat-header-row *matHeaderRowDef="displayedColumns | toggleColumns:columns;"></mat-header-row>
                      <mat-row *matRowDef="let row; columns: displayedColumns | toggleColumns:columns;"></mat-row>
                    </mat-table>
                  `
                })
                export class DynamicTableComponent {
                  private _columns = [
                    {
                      name: "date",
                      show: true
                    }, {
                      name: "selected",
                      show: true
                    }, {
                      name: "id",
                      show: true
                    }, {
                      name: "location",
                      show: true
                    }
                  ];
                
                  get columns() { return this._columns; }
                  get displayedColumns(): string[] { return this._columns.map(c => c.name); }
                }
                
                @Pipe({
                  name: "toggleColumns"
                })
                export class ToggleColumnsPipe implements PipeTransform {
                  transform(displayedColumns: string[], columns): string[] {
                    displayedColumns = columns.filter(c => !!c.show).map(c => c.name);
                    return displayedColumns;
                  }
                
                }
                

                现在您只需设法将列的show 属性从true &lt;=&gt; false 更改为show: false 时该列将消失,show: true 时将显示该列。正如你在mat-checkbox 看到的那样,我这样做了。

                【讨论】:

                  【解决方案11】:

                  有一种方法是为 html 和 css 代码编写一些脏代码,例如,用标识符指定每一列,然后设置规则(如 display: none;)在必要时隐藏它们。 考虑到表格将逐行而不是逐列生成。

                  但正确的方法是常见且最简单的方法是更改组件中的列映射(例如,当事件触发时) .

                  【讨论】:

                    【解决方案12】:

                    对于我来说,下面的 css 代码不起作用。

                    display:none 
                    

                    感谢 Rod Astrada,我尝试将以下代码添加到 ma​​t-h​​eader-cell 中,然后运行,然后运行!

                    [style.display]="'none'"
                    

                    像下面的例子:

                          <ng-container matColumnDef="id">
                            <mat-header-cell *matHeaderCellDef [style.display]="'none'">Id</mat-header-cell>
                            <mat-cell *matCellDef="let element" [style.display]="'none'"> {{element.id}} </mat-cell>
                          </ng-container>
                    

                    【讨论】:

                      【解决方案13】:

                      例如:

                      在 HTML 中:

                      <button mat-raised-button color="primary" (click)="show_hide_details()">
                          <span *ngIf="showHideDetails== true">Hide Details</span>
                          <span *ngIf="showHideDetails== false">Show Details</span>
                      </button>
                      
                      <ng-container matColumnDef="Cost">
                          <th mat-header-cell *matHeaderCellDef mat-sort-header
                          [ngStyle]="{display: showHideDetails === true? 'table-cell' : 'none'}">{{'Cost' | translate}}</th>
                      
                          <td mat-cell *matCellDef="let element" [ngStyle]="{display: showHideDetails === true? 
                           'table-cell' : 'none'}">{{element.cost}} </td>
                      </ng-container>
                      

                      在 TS 中:

                      showHideDetails: boolean = false;
                      
                      show_hide_details() {
                      this.showHideDetails= !this.showHideDetails;
                      }
                      

                      【讨论】:

                        【解决方案14】:

                        您可以使用此方法在 mat-table 中删除或添加列。

                        columnsToDisplay: string[] = ['id', 'vcName', 'vcFamily', 'Phone']
                        
                        
                          addOrRemoveTableColumn(colName: string, index: number) {
                        
                            if ( this.columnsToDisplay.filter(q => q.valueOf() == colName).length > 0) {
                              this.columnsToDisplay = this.columnsToDisplay.filter(q => q.valueOf() != colName);
                            }
                            else if (this.columnsToDisplay.filter(q => q.valueOf() == colName).length == 0) {
                              this.columnsToDisplay.splice(index, 0, colName);
                            }
                          }
                        

                        例如:

                        this.addOrRemoveTableColumn("id",6);
                        

                        【讨论】:

                          【解决方案15】:

                          响应方式:

                          希望它仍然有帮助:)

                          在 TS 中:

                          styleUrls: ['style.component.scss'],
                          

                          在 style.component.scss 中:

                            /* language=SCSS */
                          .hidden {
                              display: none;
                          }
                          
                          @media (min-width: 1280px) {
                              .lg\:block {
                                  display: table-cell !important;
                              }
                          } 
                          

                          在 HTML 中:

                            <table mat-table
                                   [dataSource]="dataSource">
                             
                              <th class="hidden lg:block"
                                  mat-header-cell
                                  *matHeaderCellDef>HEADER
                              </th>
                          
                              <td class="hidden lg:block"
                                  mat-cell
                                  *matCellDef="let item">{{ item.data }} </td>
                          
                             </table>
                          

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 2015-10-23
                            • 2020-02-05
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2017-05-15
                            • 2018-12-16
                            相关资源
                            最近更新 更多