在Angular/RXJS中向对象数组的Obervable添加/删除对象?
目标:将对象添加到现有可观察对象数组中。最后一步是在DOM上进行此反射在Angular/RXJS中向对象数组的Obervable添加/删除对象?,angular,typescript,rxjs,observable,behaviorsubject,Angular,Typescript,Rxjs,Observable,Behaviorsubject,目标:将对象添加到现有可观察对象数组中。最后一步是在DOM上进行此反射 NewObject.ts: export class NewObject { name: string; title: string; } import { Observable } from 'rxjs'; import { Component, OnInit, Inject, EventEmitter } from '@angular/core'; import { NewObject } from 'obje
NewObject.ts
:
export class NewObject {
name: string;
title: string;
}
import { Observable } from 'rxjs';
import { Component, OnInit, Inject, EventEmitter } from '@angular/core';
import { NewObject } from 'objects';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit {
// Initializing the object array Observable from a service (step 1)
readonly objects$: Observable<NewObject[]> = this.objectSvc.getAllObjects("objects").pipe(
map(obj => obj.map(x => ({ name: x.name, title: alterString(x.title) }))),
shareReplay(1)
);
constructor(
private objectSvc: ObjectService
) { }
ngOnInit() {
somethingThatHappensToAdd = (response: any) => {
let data = JSON.parse(response);
data.forEach(x => {
let obj: NewObject = { name: x.name, title: alterString(x.title) }
// Here's where I'm trying to add the obj object into the already existing object array Observable
});
};
somethingThatHappensToDelete = (response: any) => {
let data = JSON.parse(response);
data.forEach(x => {
let obj: NewObject = { name: x.name, title: alterString(x.title) }
// Here's where I'm trying to delete the obj object from the already existing object array Observable
});
};
}
}
import { Injectable } from '@angular/core';
import { Observable, throwError, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { ClientApi, ApiException, NewObject } from '../client-api.service';
@Injectable({
providedIn: 'root'
})
export class ObjectService {
constructor(
private clientApi: ClientApi
) { }
getAllObjects(name: string): Observable<NewObject[]> {
return this.clientApi.getAllObjects(name)
.pipe(
map((x) => x.result),
catchError(err => {
if (ApiException.isApiException(err)) {
if (err.status === 404) {
return of<NewObject[]>(undefined);
}
}
return throwError(err);
})
);
}
}
下面是示例.component.ts
:
export class NewObject {
name: string;
title: string;
}
import { Observable } from 'rxjs';
import { Component, OnInit, Inject, EventEmitter } from '@angular/core';
import { NewObject } from 'objects';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit {
// Initializing the object array Observable from a service (step 1)
readonly objects$: Observable<NewObject[]> = this.objectSvc.getAllObjects("objects").pipe(
map(obj => obj.map(x => ({ name: x.name, title: alterString(x.title) }))),
shareReplay(1)
);
constructor(
private objectSvc: ObjectService
) { }
ngOnInit() {
somethingThatHappensToAdd = (response: any) => {
let data = JSON.parse(response);
data.forEach(x => {
let obj: NewObject = { name: x.name, title: alterString(x.title) }
// Here's where I'm trying to add the obj object into the already existing object array Observable
});
};
somethingThatHappensToDelete = (response: any) => {
let data = JSON.parse(response);
data.forEach(x => {
let obj: NewObject = { name: x.name, title: alterString(x.title) }
// Here's where I'm trying to delete the obj object from the already existing object array Observable
});
};
}
}
import { Injectable } from '@angular/core';
import { Observable, throwError, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { ClientApi, ApiException, NewObject } from '../client-api.service';
@Injectable({
providedIn: 'root'
})
export class ObjectService {
constructor(
private clientApi: ClientApi
) { }
getAllObjects(name: string): Observable<NewObject[]> {
return this.clientApi.getAllObjects(name)
.pipe(
map((x) => x.result),
catchError(err => {
if (ApiException.isApiException(err)) {
if (err.status === 404) {
return of<NewObject[]>(undefined);
}
}
return throwError(err);
})
);
}
}
这是我的服务对象.service.ts
:
export class NewObject {
name: string;
title: string;
}
import { Observable } from 'rxjs';
import { Component, OnInit, Inject, EventEmitter } from '@angular/core';
import { NewObject } from 'objects';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit {
// Initializing the object array Observable from a service (step 1)
readonly objects$: Observable<NewObject[]> = this.objectSvc.getAllObjects("objects").pipe(
map(obj => obj.map(x => ({ name: x.name, title: alterString(x.title) }))),
shareReplay(1)
);
constructor(
private objectSvc: ObjectService
) { }
ngOnInit() {
somethingThatHappensToAdd = (response: any) => {
let data = JSON.parse(response);
data.forEach(x => {
let obj: NewObject = { name: x.name, title: alterString(x.title) }
// Here's where I'm trying to add the obj object into the already existing object array Observable
});
};
somethingThatHappensToDelete = (response: any) => {
let data = JSON.parse(response);
data.forEach(x => {
let obj: NewObject = { name: x.name, title: alterString(x.title) }
// Here's where I'm trying to delete the obj object from the already existing object array Observable
});
};
}
}
import { Injectable } from '@angular/core';
import { Observable, throwError, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { ClientApi, ApiException, NewObject } from '../client-api.service';
@Injectable({
providedIn: 'root'
})
export class ObjectService {
constructor(
private clientApi: ClientApi
) { }
getAllObjects(name: string): Observable<NewObject[]> {
return this.clientApi.getAllObjects(name)
.pipe(
map((x) => x.result),
catchError(err => {
if (ApiException.isApiException(err)) {
if (err.status === 404) {
return of<NewObject[]>(undefined);
}
}
return throwError(err);
})
);
}
}
从'@angular/core'导入{Injectable};
从“rxjs”导入{可观察的,投掷者,of};
从“rxjs/operators”导入{map,catchError};
从“../client api.service”导入{ClientApi,ApiException,NewObject};
@注射的({
providedIn:'根'
})
导出类对象服务{
建造师(
私人客户:客户
) { }
GetAllObject(名称:string):可观察{
返回此.clientApi.getAllObject(名称)
.烟斗(
映射((x)=>x.result),
catchError(err=>{
if(apieexception.isapieexception(err)){
如果(错误状态===404){
返回(未定义);
}
}
回程抛掷器(err);
})
);
}
}
在JSON
中格式化响应后,我希望能够将obj
对象插入到objects$
Observable中,并使其反映在UI上
建议我使用
BehaviorSubject
元素来实现这一点。有人可以建议如何轻松地完成此操作吗?您可以创建一个行为子对象
来发出来自某个事件的结果()
,并使用组合测试()
将结果与来自服务的结果合并
objectsFromService$ = this.objectSvc.getAllObjects("objects").pipe(
map(obj => obj.map(x => ({ name: x.name, title: alterString(x.title) })))
);
resultsArray = []
resultsSubject = new BehaviorSubject(this.resultsArray);
results$ = this.resultsSubject.asObservable()
readonly objects$: Observable<NewObject[]> = combineLatest(
this.results$,
this.objectsFromService$
).pipe(
map(([results, objects]) => ([...results, ...objects])),
shareReplay(1)
)
somethingThatHappens = (response: any) => {
let data = JSON.parse(response);
data.forEach(x => {
let obj: NewObject = { name: x.name, title: alterString(x.title) }
this.resultsArray.push(obj)
});
this.resultsSubject.next(this.resultsArray)
};
objectsFromService$=this.objectSvc.getAllObject(“对象”).pipe(
map(obj=>obj.map(x=>({name:x.name,title:alterString(x.title)})))
);
结果数组=[]
结果主题=新行为主题(this.resultsArray);
结果$=this.resultsubject.asObservable()
只读对象$:可观察=组合相关测试(
此。结果$,
此.objectsFromService$
).烟斗(
映射(([结果,对象]=>([…结果,…对象]),
共享重播(1)
)
somethingthappens=(响应:any)=>{
让data=JSON.parse(响应);
data.forEach(x=>{
让obj:NewObject={name:x.name,title:alterString(x.title)}
this.resultsArray.push(obj)
});
this.resultsubject.next(this.resultsArray)
};
我创建了一个有效的stackblitz项目:
希望这能给你一个线索。我认为哈伦的答案是好的() 如果您只更新此可观察对象一次(在init上),您可以执行以下简单操作:
export class ExampleComponent implements OnInit {
let objects$: Observable<NewObject[]>;
constructor(
private objectSvc: ObjectService
) { }
private initializeObservable() {
return this.objectSvc.getAllObjects("objects").pipe(
map(obj => obj.map(x => ({ name: x.name, title: alterString(x.title) }))),
shareReplay(1)
);
}
private getObservableWithNewValues() {
const response = callService();
let array = [];
let data = JSON.parse(response);
data.forEach(x => {
let obj: NewObject = { name: x.name, title: alterString(x.title) }
array.push(obj);
});
// This creates an observable of the array
return of(array);
}
ngOnInit() {
const initialObservable = this.initializeObservable();
const anotherObservable = this.getObservableWithNewValues();
this.objects$ = concat(initialObservable, anotherObservable);
}
}
导出类ExampleComponent实现OnInit{
让对象$:可观察;
建造师(
私有objectSvc:ObjectService
) { }
private initializeObservable(){
返回此.objectSvc.getAllObject(“对象”).pipe(
map(obj=>obj.map(x=>({name:x.name,title:alterString(x.title)})),
共享重播(1)
);
}
私有getObservableWithNewValues(){
const response=callService();
让数组=[];
让data=JSON.parse(响应);
data.forEach(x=>{
让obj:NewObject={name:x.name,title:alterString(x.title)}
阵列推送(obj);
});
//这将创建阵列的可观察状态
返回(数组);
}
恩戈尼尼特(){
const initialObservable=this.initializeObservable();
const anotherObservable=this.getObservableWithNewValues();
this.objects$=concat(初始可观察,另一个可观察);
}
}
参考文献:
构造函数(私有myService:myService){
this.myService.getObjects().subscribe(x=>this.somethingthappenstoad(x));
}
结果数组=[]
结果主题=新行为主题(this.resultsArray);
只读对象$:可观察=组合相关测试(
此.resultsSubject,
).烟斗(
映射(([results])=>([…results]),
共享重播(1)
)
已加载的某些内容(数组值){
arrayOfValues.forEach(x=>{
此.resultsArray.push(x)
});
this.resultsubject.next(this.resultsArray)
};
删除(o:任何){
//这与仅访问This.resultsArray相同
让newArray:any[]=this.resultsSubject.getValue();
for(设i=newArray.length-1;i>=0;i--){
if(newArray[i]==o){
新阵列拼接(i,1);
}
}
this.resultsubject.next(newArray);
}
解决方案2:
deleteSubject=新主题();
addSubject=新主题();
objects$=this.myService.getObjects().pipe(
switchMap(x=>merge(
在(x)中,
this.deleteSubject.pipe(映射(y=>this.deleteAll(y,x)),
this.addSubject.pipe(映射(y=>{x.push(…y);返回x;}))
)),
共享重播(1)
);
构造函数(私有myService:myService){}
deleteAll(o:any,v:any[])){
对于(设i=v.length-1;i>=0;i--){
如果(v[i]==o){
v、 拼接(i,1);
}
}
返回v;
}
在向阵列添加其他项目时,这是一个极好的解决方案。如果您要删除项目,这会导致问题吗?很高兴它对您有效:)这不会导致任何问题类似于删除有点问题,您能提供任何帮助吗,我复制了stackblitz:当然。我明天一到我的电脑就会看一看你分享的代码。问题是您正试图删除来自服务的项目。为了删除它们,您需要将其从服务的可观察的源中删除,因为您要使用async
管道。