Angular - 编辑一个数组类型的主题
Angular - Edit a Subject which is a type of Array
我正在编写一个应用程序,管理员可以在其中升级用户的权限。
在我向服务器发送请求以增加用户的权力之后。我从服务器返回用户列表:
powerUp(id: number) {
return this.http
.post<Hero[]>(environment.apiUrl + 'heroes/powerUp/' + id, {})
.pipe(
map((heroes) => {
this.currentHeroes.next(hero);
})
);
}
这里是主题:
private currentHeroes = new BehaviorSubject<Hero[]>(null);
currentHeroes$ = this.currentHeroes.asObservable();
问题是它不是主事,因为我可以从服务器 return 只有正在启动的特定用户。
powerUp(id: number) {
return this.http
.post<Hero[]>(environment.apiUrl + 'heroes/powerUp/' + id, {})
.pipe(
map((hero) => {
// update the particular hero in the currentHeroes subject
})
);
}
我的问题是如何在不从服务器返回整个列表的情况下修改 currentHeroes 主题(仅更新的用户)without.next()。
我试过以下:
powerUp(id: number) {
return this.http
.post<Hero>(environment.apiUrl + 'heroes/powerUp/' + id, {})
.pipe(
map((updatedHero) => {
this.currentHeroes$.pipe(
// doesn't enter here
map((oldHeroes) => {
const index = oldHeroes.findIndex((hero) => hero.id === id);
oldHeroes[index] = updatedHero;
})
);
})
);
}
英雄卡模板
export class HeroCardComponent implements OnInit {
@Input() hero: Hero;
constructor(public heroService: HeroService, private toastr: ToastrService) {}
ngOnInit(): void {}
powerUp(id: number, name: string) {
this.heroService.powerUp(id).subscribe(() => {
this.toastr.success(`${name} was successfully powered up!`);
});
}
delete(id: number, name: string) {
this.heroService.delete(id).subscribe(() => {
this.toastr.success(`${name} was successfully deleted`);
});
}
}
有人可以解释一下我该怎么做吗?
您可以替换之前的 currentHeroes$
,如果您使用的是 async
管道,它应该开箱即用。
如果您的模板如下所示:
<div *ngFor="let hero of (currentHeroes$ | async)">
<app-hero-card [hero]="hero"></app-hero-card>
</div>
您的组件可能如下所示:
@Component({…})
export class HeroListComponent {
currentHeroes$: Observable<Hero[]>
constructor(private heroService: HeroService) {
this.currentHeroes$ = this.heroService.getHeroes()
}
powerUp(heroId: string) {
this.currentHeroes$ = this.heroService.powerUp(heroId).pipe(
switchMap(updatedHero => {
return this.currentHeroes$.pipe(
map(oldHeroes => {
const index = oldHeroes.findIndex(hero => hero.id === updatedHero.id)
oldHeroes[index]=updatedHero
return oldHeroes
})
);
})
);
}
}
现在对魔术进行一些解释:
- HeroService.powerUp(heroId) 将 return 我们一个 observable,一旦网络请求完成,它将发出更新的英雄
- 然后我们通过应用来自 RxJS 的
switchMap
管道来转换可观察对象。 switchMap 所做的是它允许说;好的,无论这里发生什么,它都将由另一个可观察对象(我们 return) 处理
- 在 returned Observable 上,我们只是获取旧的
currentHeroes$
observable 并通过查找它的 id 并更新数组项来替换旧的英雄。最后 return 更新数组
小费
如果后端 return 更新了列表或者您可以触发重新获取,代码会少很多
如果后端return是完整列表
powerUp(heroId:string) {
this.currentHeroes$ = this.heroService.powerUp(heroId)
}
如果要触发重新获取
powerUp(heroId:string) {
this.currentHeroes$ = this.heroService.powerUp(heroId).pipe(
switchMap(_updatedHero => this.heroService.getHeroes())
);
}
我正在编写一个应用程序,管理员可以在其中升级用户的权限。
在我向服务器发送请求以增加用户的权力之后。我从服务器返回用户列表:
powerUp(id: number) {
return this.http
.post<Hero[]>(environment.apiUrl + 'heroes/powerUp/' + id, {})
.pipe(
map((heroes) => {
this.currentHeroes.next(hero);
})
);
}
这里是主题:
private currentHeroes = new BehaviorSubject<Hero[]>(null);
currentHeroes$ = this.currentHeroes.asObservable();
问题是它不是主事,因为我可以从服务器 return 只有正在启动的特定用户。
powerUp(id: number) {
return this.http
.post<Hero[]>(environment.apiUrl + 'heroes/powerUp/' + id, {})
.pipe(
map((hero) => {
// update the particular hero in the currentHeroes subject
})
);
}
我的问题是如何在不从服务器返回整个列表的情况下修改 currentHeroes 主题(仅更新的用户)without.next()。
我试过以下:
powerUp(id: number) {
return this.http
.post<Hero>(environment.apiUrl + 'heroes/powerUp/' + id, {})
.pipe(
map((updatedHero) => {
this.currentHeroes$.pipe(
// doesn't enter here
map((oldHeroes) => {
const index = oldHeroes.findIndex((hero) => hero.id === id);
oldHeroes[index] = updatedHero;
})
);
})
);
}
英雄卡模板
export class HeroCardComponent implements OnInit {
@Input() hero: Hero;
constructor(public heroService: HeroService, private toastr: ToastrService) {}
ngOnInit(): void {}
powerUp(id: number, name: string) {
this.heroService.powerUp(id).subscribe(() => {
this.toastr.success(`${name} was successfully powered up!`);
});
}
delete(id: number, name: string) {
this.heroService.delete(id).subscribe(() => {
this.toastr.success(`${name} was successfully deleted`);
});
}
}
有人可以解释一下我该怎么做吗?
您可以替换之前的 currentHeroes$
,如果您使用的是 async
管道,它应该开箱即用。
如果您的模板如下所示:
<div *ngFor="let hero of (currentHeroes$ | async)">
<app-hero-card [hero]="hero"></app-hero-card>
</div>
您的组件可能如下所示:
@Component({…})
export class HeroListComponent {
currentHeroes$: Observable<Hero[]>
constructor(private heroService: HeroService) {
this.currentHeroes$ = this.heroService.getHeroes()
}
powerUp(heroId: string) {
this.currentHeroes$ = this.heroService.powerUp(heroId).pipe(
switchMap(updatedHero => {
return this.currentHeroes$.pipe(
map(oldHeroes => {
const index = oldHeroes.findIndex(hero => hero.id === updatedHero.id)
oldHeroes[index]=updatedHero
return oldHeroes
})
);
})
);
}
}
现在对魔术进行一些解释:
- HeroService.powerUp(heroId) 将 return 我们一个 observable,一旦网络请求完成,它将发出更新的英雄
- 然后我们通过应用来自 RxJS 的
switchMap
管道来转换可观察对象。 switchMap 所做的是它允许说;好的,无论这里发生什么,它都将由另一个可观察对象(我们 return) 处理
- 在 returned Observable 上,我们只是获取旧的
currentHeroes$
observable 并通过查找它的 id 并更新数组项来替换旧的英雄。最后 return 更新数组
小费
如果后端 return 更新了列表或者您可以触发重新获取,代码会少很多
如果后端return是完整列表
powerUp(heroId:string) {
this.currentHeroes$ = this.heroService.powerUp(heroId)
}
如果要触发重新获取
powerUp(heroId:string) {
this.currentHeroes$ = this.heroService.powerUp(heroId).pipe(
switchMap(_updatedHero => this.heroService.getHeroes())
);
}