仅从 Angular 视图调用方法一次
Calling a method from an Angular view only once
我用 angular 材料建造了一个 table。我有一个名为“matricula”的对象,在第一列中,我从矩阵列表中打印 属性 matricula.matricula。在第二列中,我想打印一些数据,我从 matricula.matricula 调用了一个方法。我在我的 Typescrypt 文档中定义了我的方法,但由于它与 Web 服务一起使用,我只想为每时每刻显示的对象调用该方法(随着我有一个分页器而变化)。我已经尝试使用 {{method}} 从视图中调用该方法,但由于 Angular 视图是实时工作的,因此该方法一直被调用,项目崩溃了。
我怎样才能为每个对象矩阵只调用一次?我确信这一定是可能的,但我不知道应该使用哪种工具或方法。
这是视图中的代码:
<ng-container matColumnDef="matricula" style="flex: 0 0 10%;" >
<th mat-header-cell *matHeaderCellDef> Matrícula </th>
<td mat-cell *matCellDef="let matricula"height=70px> {{matricula.matricula}} </td>
</ng-container>
<ng-container matColumnDef="posicion" style="flex: 0 0 50%;">
<th mat-header-cell *matHeaderCellDef> Ubicación </th>
<td mat-cell *matCellDef="let matricula" height=70px> {{method(matricula.matricula)}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="mostrarColumnas"></tr>
<tr mat-row *matRowDef="let matricula; columns: mostrarColumnas;"></tr>
</table>
编辑:这是方法的代码:
let matricula : MatriculaBuscada = {
action : "ultima_posicion",
matricula : placa
}
this.posicionService.posicion(matricula).subscribe(datos => {
return datos;});
console.log('método getDatos')
}
posicionService 只调用一个 web 服务,它发回一个已经映射的 Json。
如果您不能“分页”您的 API(请参阅此 ),我认为最好的选择是订阅 matPaginator.changes。
我想你有一个具有两个功能的服务:getAllData - return 数据不完整 - 和 getData(id) - return 一项的辅助数据
你可以在 ngAfterViewInit 中有一些类似的东西:具有周期性元素
的典型materialtable
ngAfterViewInit() {
//I use the setTimeout for avoid
// the error "ExpressionChangedAfterItHasBeenCheckedError"
setTimeout(()=>{
//simple get the data, getAllData simply return an array os "positions"
this.dataService.getAllData().pipe(
map((res: any[]) => {
//create an object with all the properties necesary
return res.map((x) => ({
position: x, //<--this is the only I get
name: null, //the rest properties I put as null
weight: 0,
symbol: null,
yet: false, //<--add this new property
}));
})
).subscribe((res:any[])=>{
this.dataSource=new MatTableDataSource(res)
this.dataSource.paginator = this.paginator;
this.initPaginator() //<--this is the "key"
});
})
}
initPaginator(){
//I subscribe to paginator.page
//happens always you change the page or the page size
this.paginator.page.pipe(
startWith(1),
).subscribe((_) => {
//get the data that really is showed
//and filter only I not loaded before
const data = this.dataSource.filteredData
.slice(
this.paginator.pageIndex * this.paginator.pageSize,
(this.paginator.pageIndex + 1) * this.paginator.pageSize
)
.filter((x: any) => !x.yet);
//if there're data
if (data.length) {
this.isLoadingResults=true;
//create a forkJoin -and array of Observables-
//e.g. at first is a forkJoin of the array:
//[this.dataService.getData(1),
// this.dataService.getData(2),
// ...]
forkJoin(
data.map((x: any) => this.dataService.getData(x.position))
).subscribe((res: any[]) => {
//in subscribe, try to find the data
res.forEach((x) => {
let item = this.dataSource.data.find(
(d: any) => (d.position == x.position)
);
//and put the properties I received
if (item) {
item.name=x.name;
item.weight=x.weight;
item.symbol=x.symbol;
item.yet=true;
}
});
this.isLoadingResults=false
});
}
});
}
可以看到the stackblitz
我用 angular 材料建造了一个 table。我有一个名为“matricula”的对象,在第一列中,我从矩阵列表中打印 属性 matricula.matricula。在第二列中,我想打印一些数据,我从 matricula.matricula 调用了一个方法。我在我的 Typescrypt 文档中定义了我的方法,但由于它与 Web 服务一起使用,我只想为每时每刻显示的对象调用该方法(随着我有一个分页器而变化)。我已经尝试使用 {{method}} 从视图中调用该方法,但由于 Angular 视图是实时工作的,因此该方法一直被调用,项目崩溃了。
我怎样才能为每个对象矩阵只调用一次?我确信这一定是可能的,但我不知道应该使用哪种工具或方法。
这是视图中的代码:
<ng-container matColumnDef="matricula" style="flex: 0 0 10%;" >
<th mat-header-cell *matHeaderCellDef> Matrícula </th>
<td mat-cell *matCellDef="let matricula"height=70px> {{matricula.matricula}} </td>
</ng-container>
<ng-container matColumnDef="posicion" style="flex: 0 0 50%;">
<th mat-header-cell *matHeaderCellDef> Ubicación </th>
<td mat-cell *matCellDef="let matricula" height=70px> {{method(matricula.matricula)}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="mostrarColumnas"></tr>
<tr mat-row *matRowDef="let matricula; columns: mostrarColumnas;"></tr>
</table>
编辑:这是方法的代码:
let matricula : MatriculaBuscada = {
action : "ultima_posicion",
matricula : placa
}
this.posicionService.posicion(matricula).subscribe(datos => {
return datos;});
console.log('método getDatos')
}
posicionService 只调用一个 web 服务,它发回一个已经映射的 Json。
如果您不能“分页”您的 API(请参阅此
我想你有一个具有两个功能的服务:getAllData - return 数据不完整 - 和 getData(id) - return 一项的辅助数据
你可以在 ngAfterViewInit 中有一些类似的东西:具有周期性元素
的典型materialtable ngAfterViewInit() {
//I use the setTimeout for avoid
// the error "ExpressionChangedAfterItHasBeenCheckedError"
setTimeout(()=>{
//simple get the data, getAllData simply return an array os "positions"
this.dataService.getAllData().pipe(
map((res: any[]) => {
//create an object with all the properties necesary
return res.map((x) => ({
position: x, //<--this is the only I get
name: null, //the rest properties I put as null
weight: 0,
symbol: null,
yet: false, //<--add this new property
}));
})
).subscribe((res:any[])=>{
this.dataSource=new MatTableDataSource(res)
this.dataSource.paginator = this.paginator;
this.initPaginator() //<--this is the "key"
});
})
}
initPaginator(){
//I subscribe to paginator.page
//happens always you change the page or the page size
this.paginator.page.pipe(
startWith(1),
).subscribe((_) => {
//get the data that really is showed
//and filter only I not loaded before
const data = this.dataSource.filteredData
.slice(
this.paginator.pageIndex * this.paginator.pageSize,
(this.paginator.pageIndex + 1) * this.paginator.pageSize
)
.filter((x: any) => !x.yet);
//if there're data
if (data.length) {
this.isLoadingResults=true;
//create a forkJoin -and array of Observables-
//e.g. at first is a forkJoin of the array:
//[this.dataService.getData(1),
// this.dataService.getData(2),
// ...]
forkJoin(
data.map((x: any) => this.dataService.getData(x.position))
).subscribe((res: any[]) => {
//in subscribe, try to find the data
res.forEach((x) => {
let item = this.dataSource.data.find(
(d: any) => (d.position == x.position)
);
//and put the properties I received
if (item) {
item.name=x.name;
item.weight=x.weight;
item.symbol=x.symbol;
item.yet=true;
}
});
this.isLoadingResults=false
});
}
});
}
可以看到the stackblitz