Angular 6 向 Observable 中添加项目

29

我是Angular 6的新手,我在如何将对象添加到服务中的observable上遇到了麻烦。

我有这个observable:

 getContacts(){
  return this.contact = 
  this.http.get('https://jsonplaceholder.typicode.com/users');
 }

我需要通过另一个函数向那个可观察对象添加一项

addContact(item){
 //observable insertion goes here.
}

这是我的完整服务代码

export class ContactService {

contact;
details;

constructor(private http: HttpClient) {}

getContacts(){
 return this.contact = 
 this.http.get('https://jsonplaceholder.typicode.com/users');
}

addContact(contactName: string, contactPhone: string){

}

}

似乎你需要使用 RxJS 的 forkJoin。 - Suresh Kumar Ariya
1
我不理解你想要实现什么。Observables只支持你从服务器获取消息,它们不直接包含数据本身。只有当你通过subscribe()方法订阅Observable时,才能获取联系人/用户数据。文档比我更好地解释了这一点(https://angular.io/guide/observables)。无论如何,你可能想要向你的联系人添加一个项目? - gillesB
1
@gillesB 是的,这正是我想要的,但只在当前实例中添加联系人,而不是在服务器上。 - Francis Rubia
很难将此作为注释阅读。请编辑您的答案并将代码放在那里。 - gillesB
1
@gillesB 我编辑了我的问题。最后一部分是我完整的服务代码。 - Francis Rubia
3个回答

38

如果 this.contacts 是一个对象列表的 Observable (contacts: Observable<Items[]>) 并且您想对该列表进行一些更改,则可以简单地使用 tap

import { tap } from 'rxjs/operators';

this.contacts.pipe(tap(usersList => {
  usersList.push(newItem);
}));

但是如果您想向服务器发出另一个请求并合并这些列表,您可以使用merge

import { merge } from 'rxjs';

merge(
  this.contacts,
  this.http.get('https://jsonplaceholder.typicode.com/other_users');
).pipe(
  map(data => {
    const [currentResult, pastResult] = data;
    // ...
  }
));

更新

根据您的评论所述,您不需要对可观察对象进行任何操作。您需要的是像这样的东西:

在您的contacts.service.ts文件中:

getContacts(){
  return this.http.get('https://jsonplaceholder.typicode.com/users');
}

在你的contacts.component.ts文件中:

contacts: any[] = [];
ngOnInit() {
  this.contactsService.getContacts().subscribe(data => {
    this.contacts = data;
  });
}

addContact(item) {
  this.contacts.push(item);
}

但是,如果你想将你的联系人列表作为可观察对象,你应该使用一个Subject

在你的contacts.service.ts文件中:

contactsChange$ = new Subject<any>();
private contactsList = [];

getContacts(){
  return this.http.get('https://jsonplaceholder.typicode.com/users').pipe(tap(data => {
    this.contactsList = data;
    this.contactsChange$.next(this.contactsList);
  }));
}

addContact(item) {
  this.contactsList.push(item);
  this.contactsChange$.next(this.contactsList);
}

在您的 contacts.component.ts 文件中:

contacts: any[] = [];
ngOnInit() {
  this.contactsService.getContacts().subscribe(data => {this.contacts = data});
  this.contactsService.contactsChange$.subscribe(data => {this.contacts = data});
}

我尝试了这个,但对我好像没用。没有错误,但我看不到新添加的项目。 - Francis Rubia
我正在初始化时进行订阅。页面加载后,我应该从jsonplaceholder.com看到这些默认用户,并在添加联系人后能够从列表中看到更改。我应该如何正确地做到这一点? - Francis Rubia
@FrancisRubia 我已经更新了我的答案。请查看一下。 - Vahid
2
这是一个很棒的答案!我想补充一点小注:美元符号应该放在变量名的末尾,以明确它是一个可观察/主题而不是事件。 - denns
这个答案的更新版本做得很好,谢谢! - MikhailRatner
显示剩余3条评论

3

使用 Observables


在您的服务中

private contactInsertedSubject = new Subject<Contact>();
contactInsertedActions$ = this.contactInsertedSubject.asObservable();

 public contacts$ = this.http.get<Contact[]>(this.contactsUrl)
            .pipe(
              // tap(data => console.log('Contacts: ', JSON.stringify(data))),
              catchError(this.handleError)
            );
public contactsWithAdd$ = merge(this.contacts$, this.contactInsertedActions$)
                        .pipe(
                          scan((acc: Product[], value: Product) => [...acc, value])
                        );
addContact(newContact?: Contact) {
   this.contactInsertedSubject.next(newContact);
}

您的联系方式组件类
contacts$ = this.contactService.contactsWithAdd$;
onAdd(): void {
   this.contactService.addProduct();
}

当调用此添加方法时,服务中的主题将发出值,并且合并可观察对象具有两个输入可观察对象,如果任何一个会发出值,那么这将自动调用,然后在管道地图运算符中将执行插入工作,并且contactWithAdd可观察对象将具有更新后的列表。


0

addContact() 方法是你订阅 observable getContacts() 的地方:

getContacts(): Observable<any> {   
    return this.contact = 
    this.http.get('https://jsonplaceholder.typicode.com/users');
}

在订阅时触发调用:

addContact(){
    let cont: Observable<contactModel>;
    cont = this.getContacts();
    prueba.finally(() => {
       console.log('Finally callback')
    })
    cont.subscribe(res => {
        console.log('at the time of subscription is when the call is triggered')
        let resp: contactModel[];
        resp = res.json() as contactModel[];  
    });


}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接