Угловая 11 — мат-сортировка не работает в ng-модальной таблице

#angular #sorting #angular-material #ng-modal

Вопрос:

сортировка по мату и пагинатор не работают в ng-модальной таблице. Но вне модального он работает должным образом. Есть ли какие-либо обходные пути для решения этой проблемы?

Ответ №1:

Проблема в том, что, когда вы пытаетесь указать сортировку по мату, сортировка по мату недоступна, потому что на самом деле она не отображается. Вам нужно указать мат-сортировку после отображения. Если вы используете мат-диалог, при открытии используйте setTimeout(). Вы можете подумать о setTimeout, когда говорите Angular: «После рендеринга не забудьте выполнить эту инструкцию».

 const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
  width: '250px',
  data: {name: this.name, animal: this.animal}
});
setTimeout(()=>{ //<--here you say to Angular the sort
   this.dataSource.sort = this.sort;
})
 

Если вы используете модальный ng-bootstrap

 open(content) {
    this.modalService.open(content, {ariaLabelledBy: 'modal-basic-title'}).result.then((result) => {
      this.closeResult = `Closed with: ${result}`;
    }, (reason) => {
      this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
    });
    setTimeout(()=>{ //<--here you say to Angular the sort
       this.dataSource.sort = this.sort;
    })
  }
 

ПРИМЕЧАНИЕ: помните, что, поскольку таблица мата не видна все время, представление сортировки мата должно быть похоже

 @ViewChild(MatSort) sort: MatSort;
 

НЕ использовать {static true} -статическое значение true используется только в том случае, если элемент всегда отображается в компоненте-

Обновление действительно предложенное решение не работает. Внутри шаблона «ViewChild недоступны. Так что единственное, что я получаю, — это создать директиву дурака

 @Directive({
  selector: '[fool]',
  exportAs: 'fool'
})
export class FoolDirective implements OnInit {
  ngOnInit()
  {
    setTimeout(()=>{
      (this.table.dataSource as any).sort=this.sort
    })
  }
  constructor(@Optional() private sort:MatSort,@Optional() private table:MatTable<any>){}
}
 

Итак, нам нужно только добавить эту директиву в нашу таблицу

 <table mat-table [dataSource]="dataSource"
  matSort fool
  class="mat-elevation-z8">
 ....
</table>
 

Смотрите [stackblitz][1]

Update2 Для добавления пагинатора все сложнее. Моя идея состоит в том, чтобы улучшить нашу директивную функцию, добавив MatPaginator в качестве опции и отправив в качестве вывода

 export class FoolDirective implements OnInit {
  @Output() paginatorLoaded:EventEmitter<MatPaginator>=new EventEmitter<MatPaginator>()
  ngOnInit()
  {
    setTimeout(()=>{
      if (this.table amp;amp; this.sort)
        (this.table.dataSource as any).sort=this.sort
      if (this.paginator)
        this.paginatorLoaded.emit(this.paginator)
    })
  }
  constructor(@Optional() private sort:MatSort,@Optional() private table:MatTable<any>,@Optional() private paginator:MatPaginator){}
}
 

Затем, единственное, при добавлении пагинатора напишите

 <mat-paginator  fool 
         (paginatorLoaded)="dataSource.paginator=$event"
....>
</mat-paginator>
 

Единственное, что нужно изменить .css, добавив в styles.css

 .cdk-overlay-container {
  z-index: 9000;
}
 

в противном случае выбор количества страниц не отображается-он отображается, но находится под всплывающим окном

ПРИМЕЧАНИЕ: На самом деле мне не очень нравятся эти обходные пути, возможно, пришло время переосмыслить и использовать другое всплывающее окно-например, материал — или использовать модальную загрузку ngb с компонентами или шаблоном. [1]: https://stackblitz.com/edit/angular-hbadro?file=src/app/fool.directive.ts

Комментарии:

1. Я попробовал, но это не работает. Вот ссылка на stackblitz: stackblitz.com/edit/…

2. Моя Вина!! Извините, я обновляю ответ (это единственное решение, которое я могу получить)

3. Большое вам спасибо за обновленный ответ. Но у меня есть последний вопрос. Как мне это сделать с помощью пагинатора? Как я понимаю, это следует тому же принципу, что и сортировка, но в данном случае это не работает. Это мой стакблитц stackblitz.com/edit/…

4. после того, как я обдумаю проблему, я снова обновлю ответ