Angular 对象被推送后不更新对象数组
Angular doesn't update object array after object is pushed
我目前正在从事使用 angular-google-map (agm) 的项目,我使用不同的多边形来显示不同的东西。现在我想在地图上绘图,这样我就可以使用坐标集合问题是我的对象数组没有更新。
TLDR:当我使用 .push 时,对象数组没有更新。
home.component.ts
export class HomeComponent implements OnInit {
ngOnInit(): void {
}
constructor(private cr: ChangeDetectorRef) { }
//this is my polygon with initial values
pathsLs: any[] = [[
{ lat: 43.51270075713179, lng: 16.468134790981548 },
{ lat: 43.51205153579524, lng: 16.46757689150645 },
{ lat: 43.5119745090715, lng: 16.466895610416667 },
{ lat: 43.51273927004248, lng: 16.466659576023357 },
{ lat: 43.51284380496191, lng: 16.467753917301433 },
]]
pointList: { lat: number; lng: number }[] = [];
//this is function I use to update my Object array
addSomething() {
this.pathsLs.push(this.pointList);
this.pathsLs = [...this.pathsLs];
this.cr.detectChanges();
}
问题是调用此函数时我可以在 console.log(this.pathsLs) 上看到它已更新并且它甚至在地图上绘制多边形但是当我将其全部刷新回之前(初始值) ).我想我问的是有没有办法实际看到这种变化,例如:
如果我做这样的事情 this.pathsLs.push([{ lat: 43.51174, lng: 16.46538 }])
来真正进入我的打字稿:
pathsLs: any[] = [[
{ lat: 43.51270075713179, lng: 16.468134790981548 },
{ lat: 43.51205153579524, lng: 16.46757689150645 },
{ lat: 43.5119745090715, lng: 16.466895610416667 },
{ lat: 43.51273927004248, lng: 16.466659576023357 },
{ lat: 43.51284380496191, lng: 16.467753917301433 },
],[{ lat: 43.51174, lng: 16.46538 }] <-- newly added
]
您是否使用 HTML 组件来调用函数 addSomething() ?
因为你的组件没有调用它。
另一件事是你的数组'pointList',你推的是一个空数组。
关于您的日志,您可能必须推送到数组[0],因为您使用的是数组数组。
pathsLs: any[] = [[
{ lat: 43.51270075713179, lng: 16.468134790981548 },
{ lat: 43.51205153579524, lng: 16.46757689150645 },
{ lat: 43.5119745090715, lng: 16.466895610416667 },
{ lat: 43.51273927004248, lng: 16.466659576023357 },
{ lat: 43.51284380496191, lng: 16.467753917301433 },
],[{ lat: 43.51174, lng: 16.46538 }] <-- newly added
]
pathsLs: any[] = [[]],所以你是在父数组里面push,你需要在子数组里面push;
声明时似乎有问题。
pathsLs: any[] = [
{ lat: 43.51270075713179, lng: 16.468134790981548 },
{ lat: 43.51205153579524, lng: 16.46757689150645 },
{ lat: 43.5119745090715, lng: 16.466895610416667 },
{ lat: 43.51273927004248, lng: 16.466659576023357 },
{ lat: 43.51284380496191, lng: 16.467753917301433 }
]
Stackblitz
如评论中所述,如果您希望对数据进行持久更改,则需要从本地存储或服务器等持久源获取数据。
我建议采用关注点分离方法,使用处理存储的服务、充当中介的容器和获取数据并显示数据的哑 child 组件(可重用)。
使用 parent 容器组件获取路径并将它们传递给显示它们的 child 组件:
<app-child-component [pathLs]="pathLs"></app-child-component>
child通过@Input()
获取路径并显示这些
@Input() pathLs: IPathL[][] = [];
本地存储服务
import { Injectable } from '@angular/core';
import { IPathL } from './paths.model';
@Injectable()
export class PathsLocalStorageService {
constructor() {}
// not required but to make getPaths faster implemented cache
private cachePathLs: IPathL[][] | null = null;
private initialValue = [
[
{ lat: 43.51270075713179, lng: 16.468134790981548 },
{ lat: 43.51205153579524, lng: 16.46757689150645 },
{ lat: 43.5119745090715, lng: 16.466895610416667 },
{ lat: 43.51273927004248, lng: 16.466659576023357 },
{ lat: 43.51284380496191, lng: 16.467753917301433 },
],
];
getPaths(): IPathL[][] {
// if defined return cached value
if (this.cachePathLs) {
return this.cachePathLs;
}
// get pathLs from local storage
let pStrOrNull = localStorage.getItem('pathsLs');
if (pStrOrNull == null) {
// if no stored value provide following initial value
return this.initialValue;
} else {
// otherwise get from local storage
let pathLs = JSON.parse(localStorage.getItem('pathsLs')) as IPathL[][];
// save within app
this.cachePathLs = pathLs;
return pathLs;
}
}
setPaths(pathLs: IPathL[][]): void {
localStorage.setItem('pathsLs', JSON.stringify(pathLs));
}
addPath(pathL: IPathL[]): IPathL[][] {
let pathLs = this.getPaths();
// add path
pathLs.push(pathL);
// save within app
this.cachePathLs = pathLs;
// save to local storage
this.setPaths(pathLs);
return pathLs;
}
resetPaths(): IPathL[][] {
this.setPaths(this.initialValue);
this.cachePathLs = this.initialValue;
return this.initialValue;
}
}
显然API的服务可以改为Observables和服务器交互。事实上,这样做的第一步通常是首先通过本地存储模拟服务(如下所示),更改任何组件使用服务的方式,然后将服务替换为服务器交互。
import { of } from 'rxjs'
...
@Injectable()
export class PathsLocalStorageService {
...etc
resetPaths(): Observable<IPathL[][]> {
this.setPaths(this.initialValue);
this.cachePathLs = this.initialValue;
return of(this.initialValue);
}
}
我目前正在从事使用 angular-google-map (agm) 的项目,我使用不同的多边形来显示不同的东西。现在我想在地图上绘图,这样我就可以使用坐标集合问题是我的对象数组没有更新。
TLDR:当我使用 .push 时,对象数组没有更新。
home.component.ts
export class HomeComponent implements OnInit {
ngOnInit(): void {
}
constructor(private cr: ChangeDetectorRef) { }
//this is my polygon with initial values
pathsLs: any[] = [[
{ lat: 43.51270075713179, lng: 16.468134790981548 },
{ lat: 43.51205153579524, lng: 16.46757689150645 },
{ lat: 43.5119745090715, lng: 16.466895610416667 },
{ lat: 43.51273927004248, lng: 16.466659576023357 },
{ lat: 43.51284380496191, lng: 16.467753917301433 },
]]
pointList: { lat: number; lng: number }[] = [];
//this is function I use to update my Object array
addSomething() {
this.pathsLs.push(this.pointList);
this.pathsLs = [...this.pathsLs];
this.cr.detectChanges();
}
问题是调用此函数时我可以在 console.log(this.pathsLs) 上看到它已更新并且它甚至在地图上绘制多边形但是当我将其全部刷新回之前(初始值) ).我想我问的是有没有办法实际看到这种变化,例如:
如果我做这样的事情 this.pathsLs.push([{ lat: 43.51174, lng: 16.46538 }])
来真正进入我的打字稿:
pathsLs: any[] = [[
{ lat: 43.51270075713179, lng: 16.468134790981548 },
{ lat: 43.51205153579524, lng: 16.46757689150645 },
{ lat: 43.5119745090715, lng: 16.466895610416667 },
{ lat: 43.51273927004248, lng: 16.466659576023357 },
{ lat: 43.51284380496191, lng: 16.467753917301433 },
],[{ lat: 43.51174, lng: 16.46538 }] <-- newly added
]
您是否使用 HTML 组件来调用函数 addSomething() ?
因为你的组件没有调用它。
另一件事是你的数组'pointList',你推的是一个空数组。
关于您的日志,您可能必须推送到数组[0],因为您使用的是数组数组。
pathsLs: any[] = [[
{ lat: 43.51270075713179, lng: 16.468134790981548 },
{ lat: 43.51205153579524, lng: 16.46757689150645 },
{ lat: 43.5119745090715, lng: 16.466895610416667 },
{ lat: 43.51273927004248, lng: 16.466659576023357 },
{ lat: 43.51284380496191, lng: 16.467753917301433 },
],[{ lat: 43.51174, lng: 16.46538 }] <-- newly added
]
pathsLs: any[] = [[]],所以你是在父数组里面push,你需要在子数组里面push;
声明时似乎有问题。
pathsLs: any[] = [
{ lat: 43.51270075713179, lng: 16.468134790981548 },
{ lat: 43.51205153579524, lng: 16.46757689150645 },
{ lat: 43.5119745090715, lng: 16.466895610416667 },
{ lat: 43.51273927004248, lng: 16.466659576023357 },
{ lat: 43.51284380496191, lng: 16.467753917301433 }
]
Stackblitz
如评论中所述,如果您希望对数据进行持久更改,则需要从本地存储或服务器等持久源获取数据。
我建议采用关注点分离方法,使用处理存储的服务、充当中介的容器和获取数据并显示数据的哑 child 组件(可重用)。
使用 parent 容器组件获取路径并将它们传递给显示它们的 child 组件:
<app-child-component [pathLs]="pathLs"></app-child-component>
child通过@Input()
获取路径并显示这些
@Input() pathLs: IPathL[][] = [];
本地存储服务
import { Injectable } from '@angular/core';
import { IPathL } from './paths.model';
@Injectable()
export class PathsLocalStorageService {
constructor() {}
// not required but to make getPaths faster implemented cache
private cachePathLs: IPathL[][] | null = null;
private initialValue = [
[
{ lat: 43.51270075713179, lng: 16.468134790981548 },
{ lat: 43.51205153579524, lng: 16.46757689150645 },
{ lat: 43.5119745090715, lng: 16.466895610416667 },
{ lat: 43.51273927004248, lng: 16.466659576023357 },
{ lat: 43.51284380496191, lng: 16.467753917301433 },
],
];
getPaths(): IPathL[][] {
// if defined return cached value
if (this.cachePathLs) {
return this.cachePathLs;
}
// get pathLs from local storage
let pStrOrNull = localStorage.getItem('pathsLs');
if (pStrOrNull == null) {
// if no stored value provide following initial value
return this.initialValue;
} else {
// otherwise get from local storage
let pathLs = JSON.parse(localStorage.getItem('pathsLs')) as IPathL[][];
// save within app
this.cachePathLs = pathLs;
return pathLs;
}
}
setPaths(pathLs: IPathL[][]): void {
localStorage.setItem('pathsLs', JSON.stringify(pathLs));
}
addPath(pathL: IPathL[]): IPathL[][] {
let pathLs = this.getPaths();
// add path
pathLs.push(pathL);
// save within app
this.cachePathLs = pathLs;
// save to local storage
this.setPaths(pathLs);
return pathLs;
}
resetPaths(): IPathL[][] {
this.setPaths(this.initialValue);
this.cachePathLs = this.initialValue;
return this.initialValue;
}
}
显然API的服务可以改为Observables和服务器交互。事实上,这样做的第一步通常是首先通过本地存储模拟服务(如下所示),更改任何组件使用服务的方式,然后将服务替换为服务器交互。
import { of } from 'rxjs'
...
@Injectable()
export class PathsLocalStorageService {
...etc
resetPaths(): Observable<IPathL[][]> {
this.setPaths(this.initialValue);
this.cachePathLs = this.initialValue;
return of(this.initialValue);
}
}