Estoy usando una tabla de mat para enumerar el contenido de los idiomas elegidos por los usuarios. También pueden agregar nuevos idiomas usando el panel de diálogo. Después agregaron un idioma y regresaron. Quiero que mi fuente de datos se actualice para mostrar los cambios que realizaron.
Inicializo el almacén de datos obteniendo datos de usuario de un servicio y pasándolos a una fuente de datos en el método de actualización.
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
}
}
Así que intenté llamar a un método de actualización donde obtengo el usuario del backend nuevamente y luego reinicializo la fuente de datos. Sin embargo, esto no funciona, no se están produciendo cambios.
Respuestas:
Active una detección de cambios usando
ChangeDetectorRef
en elrefresh()
método justo después de recibir los nuevos datos, inyecte ChangeDetectorRef en el constructor y use detectChanges como este:fuente
No sé si
ChangeDetectorRef
se requirió cuando se creó la pregunta, pero ahora esto es suficiente:Ejemplo:
StackBlitz
fuente
MatTableDataSource.paginator
propiedad después de que se haya inicializado la vista del Paginador. Vea la descripción de lapaginator
propiedad aquí: material.angular.io/components/table/api#MatTableDataSourceEntonces, para mí, nadie dio una buena respuesta al problema que encontré, que es casi lo mismo que @Kay. Para mí se trata de ordenar, ordenar la tabla no ocurre cambios en el tapete. Propuse esta respuesta ya que es el único tema que encuentro al buscar en Google. Estoy usando Angular 6.
Como se dice aquí :
Así que solo tienes que llamar a renderRows () en tu método refresh () para que aparezcan tus cambios.
Consulte aquí la integración.
fuente
Ya que está usando
MatPaginator
, solo necesita hacer cualquier cambio en el paginador, esto activa la recarga de datos.Truco simple:
Esto actualiza el tamaño de la página al tamaño de la página actual, por lo que básicamente nada cambia, excepto que
_emitPageEvent()
también se llama a la función privada , lo que activa la recarga de la tabla.fuente
_changePageSize()
no es público, ¿verdad? ¿Es seguro de usar? Más en stackoverflow.com/questions/59093781/…Agregue esta línea debajo de su acción de agregar o eliminar la fila en particular.
fuente
La mejor manera de hacer esto es agregando un observable adicional a su implementación de Datasource.
En el método de conexión ya debería estar usando
Observable.merge
para suscribirse a una matriz de observables que incluyen paginator.page, sort.sortChange, etc. Puede agregar un nuevo sujeto a esto y llamar a next cuando necesite causar una actualización.algo como esto:
Y luego puede llamar
recordChange$.next()
para iniciar una actualización.Naturalmente, envolvería la llamada en un método refresh () y la llamaría fuera de la instancia de la fuente de datos con el componente y otras técnicas adecuadas.
fuente
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>'.
Puede usar la función de conexión de la fuente de datos
al igual que. 'datos' son los nuevos valores para la tabla de datos
fuente
Puede actualizar fácilmente los datos de la tabla usando "concat":
por ejemplo:
language.component.ts
language.component.html
Y, cuando actualiza los datos (language.component.ts):
Cuando estás usando "concat" angular, detecta los cambios del objeto (this.teachDS) y no necesitas usar otra cosa.
PD: Me funciona en los ángulos 6 y 7, no probé otra versión.
fuente
También puede utilizar el método renderRows ().
@ViewChild (MatTable, {static: false}) tabla: MatTable // inicializar
luego this.table.renderRows ();
para referencia, consulte esto: https://www.freakyjolly.com/angular-7-8-edit-add-delete-rows-in-material-table-with-using-dialogs-inline-row-operation/
fuente
Bueno, me encontré con un problema similar en el que agregué algo a la fuente de datos y no se está recargando.
La forma más fácil que encontré fue simplemente reasignar los datos
fuente
En Angular 9, el secreto es
this.dataSource.data = this.dataSource.data;
Ejemplo:
fuente
Logré una buena solución usando dos recursos:
actualizando tanto la fuente de datos como el paginador:
donde, por ejemplo, dataSource se define aquí:
fuente
fuente
en mi caso (Angular 6+), heredé de
MatTableDataSource
crearMyDataSource
. Sin llamar despuésthis.data = someArray
datos donde no se muestran
clase MyDataSource
fuente
Hay dos formas de hacerlo porque Angular Material es inconsistente y esto está muy mal documentado. La tabla de material angular no se actualizará cuando llegue una nueva fila. Sorprendentemente, se dice que se debe a problemas de rendimiento. Pero parece más un problema de diseño, no pueden cambiar. Se debe esperar que la tabla se actualice cuando se produzca una nueva fila. Si este comportamiento no debe estar habilitado de forma predeterminada, debe haber un interruptor para apagarlo.
De todos modos, no podemos cambiar el material angular. Pero básicamente podemos usar un método muy pobremente documentado para hacerlo:
Uno: si usa una matriz directamente como fuente:
donde tabla es ViewChild del mat-table
Segundo: si usa la clasificación y otras funciones
table.renderRows () sorprendentemente no funcionará. Porque mat-table es inconsistente aquí. Necesita usar un truco para decirle a la fuente que cambió. Lo haces con este método:
donde dataSource es el contenedor MatTableDataSource que se utiliza para ordenar y otras características.
fuente
Esto funcionó para mí:
fuente
Creo que el
MatTableDataSource
objeto está vinculado de alguna manera con la matriz de datos que pasa alMatTableDataSource
constructor.Por ejemplo:
Entonces, cuando tenga que cambiar datos; cambiar en la lista original
dataTable
y luego reflejar el cambio en la tabla mediante el_updateChangeSubscription()
método de llamada entableDS
.Por ejemplo:
Eso es trabajo conmigo a través de Angular 6.
fuente
_
y lo llama?Esto es trabajo para mí:
Por lo tanto, debe declarar su instancia de fuente de datos como
MatTableDataSource
fuente
Investigué un poco más y encontré este lugar para darme lo que necesitaba: se siente limpio y se relaciona con los datos de actualización cuando se actualiza desde el servidor: https://blog.angular-university.io/angular-material-data-table/
La mayoría de los créditos corresponden a la página anterior. A continuación se muestra una muestra de cómo se puede usar un selector de mat para actualizar una tabla de mat enlazada a una fuente de datos en el cambio de selección. Estoy usando Angular 7. Perdón por ser extenso, tratando de ser completo pero conciso. He arrancado tantas partes no necesarias como sea posible. ¡Con esto esperando ayudar a alguien más a avanzar más rápido!
organización.modelos.ts:
organization.service.ts:
organizationdatasource.model.ts:
organizaciones.componente.html:
organizaciones.componente.scss:
organisation.component.ts:
fuente
Después de leer Material Table que no actualiza la actualización de datos de publicación # 11638 Informe de error , encontré que la mejor (lea, la solución más fácil) fue la sugerida por el comentario final o 'shhdharmen' con una sugerencia para usar un EventEmitter.
Esto implica algunos cambios simples en la clase de fuente de datos generada
es decir, agregue una nueva variable privada a su clase de fuente de datos
y donde envío nuevos datos a la matriz interna (this.data), emito un evento.
y finalmente, cambie la matriz 'dataMutation' en el método 'connect', de la siguiente manera
fuente
// esta es la fuente de datos
this.guests = [];
this.guests.push ({id: 1, nombre: 'Ricardo'});
// actualiza el origen de datos this.guests = Array.from (this.guest);
fuente
Lancé una biblioteca destinada a ser la fuente de datos de material oficial en el futuro, que admite cualquier tipo de flujo de entrada (clasificación, paginación, filtros) y alguna configuración con depuración para ver cómo funciona mientras codifica.
Puede encontrar la demostración de StackBlitz y más información aquí:
https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6
Estaría encantado de escuchar su opinión y apoyar sus casos de uso si es necesario.
¡Feliz codificación!
fuente
Probé ChangeDetectorRef, Subject y BehaviourSubject, pero lo que me funciona
fuente