Estou usando um tapete para listar o conteúdo dos idiomas escolhidos pelos usuários. Eles também podem adicionar novos idiomas usando o painel de diálogo. Depois eles adicionaram um idioma e voltaram. Quero que minha fonte de dados seja atualizada para mostrar as alterações que eles fizeram.
Eu inicializo o armazenamento de dados obtendo dados do usuário de um serviço e passando-os para uma fonte de dados no método de atualização.
Language.component.ts
import { Component, OnInit } from '@angular/core';
import { LanguageModel, LANGUAGE_DATA } from '../../../../models/language.model';
import { LanguageAddComponent } from './language-add/language-add.component';
import { AuthService } from '../../../../services/auth.service';
import { LanguageDataSource } from './language-data-source';
import { LevelbarComponent } from '../../../../directives/levelbar/levelbar.component';
import { DataSource } from '@angular/cdk/collections';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { MatSnackBar, MatDialog } from '@angular/material';
@Component({
selector: 'app-language',
templateUrl: './language.component.html',
styleUrls: ['./language.component.scss']
})
export class LanguageComponent implements OnInit {
displayedColumns = ['name', 'native', 'code', 'level'];
teachDS: any;
user: any;
constructor(private authService: AuthService, private dialog: MatDialog) { }
ngOnInit() {
this.refresh();
}
add() {
this.dialog.open(LanguageAddComponent, {
data: { user: this.user },
}).afterClosed().subscribe(result => {
this.refresh();
});
}
refresh() {
this.authService.getAuthenticatedUser().subscribe((res) => {
this.user = res;
this.teachDS = new LanguageDataSource(this.user.profile.languages.teach);
});
}
}
language-data-source.ts
import {MatPaginator, MatSort} from '@angular/material';
import {DataSource} from '@angular/cdk/collections';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
export class LanguageDataSource extends DataSource<any> {
constructor(private languages) {
super();
}
connect(): Observable<any> {
return Observable.of(this.languages);
}
disconnect() {
// No-op
}
}
Tentei chamar um método de atualização em que obtenho o usuário do back-end novamente e reinicializo a fonte de dados. No entanto, isso não funciona, nenhuma alteração está ocorrendo.
Respostas:
Acione uma detecção de mudança usando
ChangeDetectorRef
orefresh()
método logo após receber os novos dados, injete ChangeDetectorRef no construtor e use detectChanges como este:fonte
Não sei se
ChangeDetectorRef
era necessário quando a pergunta foi criada, mas agora basta:Exemplo:
StackBlitz
fonte
MatTableDataSource.paginator
propriedade depois que a visualização do Paginator for inicializada. Veja a descrição dapaginator
propriedade aqui: material.angular.io/components/table/api#MatTableDataSourceEntão, para mim, ninguém deu uma boa resposta para o problema que encontrei que é quase o mesmo que @Kay. Para mim trata-se de classificar, a classificação da mesa não ocorre mudanças no tapete. Proponho esta resposta, pois é o único tópico que encontro pesquisando no google. Estou usando o Angular 6.
Como disse aqui :
Portanto, você só precisa chamar renderRows () em seu método refresh () para fazer suas alterações aparecerem.
Veja aqui para integração.
fonte
Já que você está usando
MatPaginator
, você só precisa fazer qualquer alteração no paginator, isso aciona a recarga dos dados.Truque simples:
Isso atualiza o tamanho da página para o tamanho da página atual, então basicamente nada muda, exceto a
_emitPageEvent()
função privada também é chamada, iniciando o recarregamento da tabela.fonte
_changePageSize()
não é público certo? É seguro usar? Mais em stackoverflow.com/questions/59093781/…Adicione esta linha abaixo de sua ação de adicionar ou excluir a linha particular.
fonte
A melhor maneira de fazer isso é adicionando um observável adicional à implementação da fonte de dados.
No método de conexão, você já deve estar usando
Observable.merge
para assinar uma matriz de observáveis que incluem paginator.page, sort.sortChange, etc. Você pode adicionar um novo assunto a isso e chamar next quando precisar causar uma atualização.algo assim:
E então você pode ligar
recordChange$.next()
para iniciar uma atualização.Naturalmente, eu envolveria a chamada em um método refresh () e a chamaria da instância da fonte de dados com o componente e outras técnicas adequadas.
fonte
Property 'connect' in type 'customDataSource<T>' is not assignable to the same property in base type 'MatTableDataSource<T>'. Type '() => Observable<any>' is not assignable to type '() => BehaviorSubject<T[]>'. Type 'Observable<any>' is not assignable to type 'BehaviorSubject<T[]>'. Property '_value' is missing in type 'Observable<any>'.
Você pode apenas usar a função de conexão da fonte de dados
igual a. 'dados' sendo os novos valores para a tabela de dados
fonte
Você pode atualizar facilmente os dados da tabela usando "concat":
por exemplo:
language.component.ts
language.component.html
E, quando você atualizar os dados (language.component.ts):
Quando você estiver usando o angular "concat" detecte as alterações do objeto (this.teachDS) e não precise usar outra coisa.
PD: Funcionou para mim no angular 6 e 7, não tentei outra versão.
fonte
Você também pode usar o método renderRows ().
@ViewChild (MatTable, {static: false}) table: MatTable // inicializar
então this.table.renderRows ();
para referência, verifique isto -: https://www.freakyjolly.com/angular-7-8-edit-add-delete-rows-in-material-table-with-using-dialogs-inline-row-operation/
fonte
Bem, eu encontrei um problema semelhante em que adicionei algo à fonte de dados e ele não estava recarregando.
A maneira mais fácil que encontrei é simplesmente reatribuir os dados
fonte
No Angular 9, o segredo é
this.dataSource.data = this.dataSource.data;
Exemplo:
fonte
Consegui uma boa solução usando dois recursos:
atualizando dataSource e paginator:
onde, por exemplo, dataSource é definido aqui:
fonte
fonte
no meu caso (Angular 6+), herdei de
MatTableDataSource
para criarMyDataSource
. Sem ligar depoisthis.data = someArray
dados onde não são exibidos
classe MyDataSource
fonte
Há duas maneiras de fazer isso porque o material angular é inconsistente e está muito mal documentado. A tabela de material angular não será atualizada quando uma nova linha chegar. Surpreendentemente, dizem que é por causa dos problemas de desempenho. Mas parece mais um problema de design, eles não podem mudar. Deve-se esperar que a tabela seja atualizada quando ocorrer uma nova linha. Se esse comportamento não deve ser ativado por padrão, deve haver um interruptor para desligá-lo.
De qualquer forma, não podemos alterar o material angular. Mas podemos basicamente usar um método muito mal documentado para fazer isso:
Um - se você usar um array diretamente como fonte:
em que table é ViewChild da mesa-tapete
Segundo - se você usar classificação e outros recursos
table.renderRows () surpreendentemente não funcionará. Porque a mesa-tapete é inconsistente aqui. Você precisa usar um hack para dizer que a fonte mudou. Você faz isso com este método:
onde dataSource é o wrapper MatTableDataSource usado para classificação e outros recursos.
fonte
Isso funcionou para mim:
fonte
Eu acho que o
MatTableDataSource
objeto está de alguma forma vinculado ao array de dados que você passa para oMatTableDataSource
construtor.Por exemplo:
Então, quando você tiver que alterar os dados; mudança na lista original
dataTable
e, em seguida, reflete a mudança na mesa por chamada_updateChangeSubscription()
método de emtableDS
.Por exemplo:
Isso é trabalho comigo por meio do Angular 6.
fonte
_
e você o chama?Isso está funcionando para mim:
Portanto, você deve declarar sua instância da fonte de dados como
MatTableDataSource
fonte
Eu fiz mais pesquisas e encontrei este lugar para me dar o que eu precisava - parece limpo e relacionado a atualização de dados quando atualizado do servidor: https://blog.angular-university.io/angular-material-data-table/
A maioria dos créditos para a página acima. Abaixo está um exemplo de como um seletor de esteira pode ser usado para atualizar uma tabela de esteira ligada a uma fonte de dados na mudança de seleção. Estou usando o Angular 7. Desculpe por ser extenso, tentando ser completo, mas conciso - rasguei o máximo possível de partes desnecessárias. Com isso na esperança de ajudar alguém a avançar mais rápido!
organization.model.ts:
organization.service.ts:
organizationdatasource.model.ts:
organizações.component.html:
organization.component.scss:
organization.component.ts:
fonte
Depois de ler a tabela de materiais não atualizando a atualização de dados de postagem # 11638, Relatório de bug eu achei que a melhor (leia, a solução mais fácil) foi sugerida pelo comentador final 'shhdharmen' com uma sugestão para usar um EventEmitter.
Isso envolve algumas mudanças simples na classe da fonte de dados gerada
ou seja) adicione uma nova variável privada à sua classe de fonte de dados
e onde coloco novos dados no array interno (this.data), emito um evento.
e, finalmente, altere a matriz 'dataMutation' no método 'conectar' - como segue
fonte
// esta é a
fonte de dados this.guests = [];
this.guests.push ({id: 1, nome: 'Ricardo'});
// atualize o dataSource this.guests = Array.from (this.guest);
fonte
Lancei uma biblioteca com o objetivo de ser o Material DataSource oficial no futuro, suportando qualquer tipo de fluxo de entrada (classificação, paginação, filtros) e alguma configuração com depuração para ver como funciona enquanto você está codificando.
Você pode encontrar a demonstração StackBlitz e mais informações aqui:
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6
Terei prazer em ouvir sua opinião e apoiar seus casos de uso, se necessário.
Boa codificação!
fonte
Eu tentei ChangeDetectorRef, Subject e BehaviourSubject, mas o que funciona para mim
fonte