我有角度4的两个组件和服务,组件1添加联系人,组件2显示联系人。我正在使用HttpClient和Observables获取所有联系人,但是当我添加一个联系人时,我的第二个组件没有更新联系人。我通过服务完成所有这些工作。联系人在启动时显示良好,但是当我触发add()函数时它们没有更新。
我的contact.service.ts
@Injectable()
export class ContactService {
constructor(private http: HttpClient, private messageService: MessageService) { }
private contactsUrl = 'api/contacts';
getContacts(): Observable<Contact[]> {
return this.http.get<Contact[]>(this.contactsUrl)
.pipe(
tap(contacts => this.log(`Fetched contacts`)),
catchError(this.handleError('getContacts', []))
);
}
getContact(id: number): Observable<Contact> {
const url = `${this.contactsUrl}/${id}`;
return this.http.get<Contact>(url).pipe(
tap(_ => this.log(`fetched contact id=${id}`)),
catchError(this.handleError<Contact>(`getContact id=${id}`))
);
}
addContact (contact: Contact): Observable<Contact> {
return this.http.post<Contact>(this.contactsUrl, contact, httpOptions).pipe(
tap((contact: Contact) => this.log(`${contact.name} added to list`)),
catchError(this.handleError<Contact>('addContact'))
);
}
}
我的contact-item.component.ts
export class ContactItemComponent implements OnInit {
contacts: Contact[] = [];
constructor(private contactService: ContactService) { }
ngOnInit(){
console.log("init");
this.getContacts();
}
getContacts(): void {
this.contactService.getContacts().subscribe(contacts => this.contacts = contacts);
}
}
我的contact-add.component.ts
export class ContactAddComponent {
contacts: Contact[] = [];
constructor(private contactService: ContactService) { }
add(name: string, surname: string, phoneNumber: number): void {
name = name.trim();
surname = surname.trim();
phoneNumber = phoneNumber;
if(!name || !surname || !phoneNumber) { return; }
this.contactService.addContact({ name, surname, phoneNumber } as Contact)
.subscribe(contact => {
this.contacts.push(contact);
})
}
答案 0 :(得分:1)
Sergio,当您添加&#34;联系人&#34;时,您可以:1)在dbs中添加联系人,2。 - 将联系人添加到contact-add.component中的阵列联系人,没有别的。你必须做更多的事情&#34; to contact-item.component接受更改。
当我们订阅contactService.getContact()时,只需要#34; getContact&#34;一次。
解决方案:
1.-服务存储联系人,我们使用getter来获取/设置值 在您的contactService
中@Injectable()
export class ContactService {
contacts: Contact[]; //declare a variable contacts
private contactsUrl = 'api/contacts';
constructor(private http: HttpClient, private messageService: MessageService) { }
getContacts(): Observable<Contact[]> {
if (this.contacts) //If yet exist, simply
return Observable.of(this.contacts);
return this.http.get<Contact[]>(this.contactsUrl)
.pipe(
tap(contacts =>{
this.log(`Fetched contacts`)
}),
catchError(this.handleError('getContacts', []))
);
}
getContact(id: number): Observable<Contact> {
...
}
addContact (contact: Contact): Observable<Contact> {
...
}
}
然后,您可以使用contact-items.component
export class ContactItemComponent implements OnInit {
//contacts is a "getter", not a variable
get contacts(){
return this.contactService.contacts;
}
set contacts(value)
{
this.contactService.contacts=value;
}
constructor(private contactService: ContactService) { }
ngOnInit(){
this.getContacts();
}
getContacts(): void {
this.contactService.getContacts().subscribe((contacts)=>{
//see that really you're changing this.contactService.contacts
this.contacts=contacts;
})
}
在您的ContactAdd-component
中export class ContactAddComponent {
//yes, in your contactAddComponent you have a getter
//contacts is a "getter", not a variable
get contacts(){
return this.contactService.contacts;
}
set contacts(value)
{
this.contactService.contacts=value;
}
constructor(private contactService: ContactService) { }
add(name: string, surname: string, phoneNumber: number): void {
name = name.trim();
surname = surname.trim();
phoneNumber = phoneNumber;
if(!name || !surname || !phoneNumber) { return; }
this.contactService.addContact({ name, surname, phoneNumber } as Contact)
.subscribe(contact => {
//really you push contact of your contactService.contact
this.contacts.push(contact);
})
}
2. - 如安德烈指示您,在您的服务中订阅一个Observable。
您的服务
@Injectable()
export class ContactService {
constructor(private http: HttpClient, private messageService: MessageService) { }
//declara a Subject
private contactsSource = new Subject<Contact>();
// Declare a observable
contactsObservable = this.contactsSource.asObservable();
private contactsUrl = 'api/contacts';
getContacts(): Observable<Contact[]> {
...
}
getContact(id: number): Observable<Contact> {
...
}
addContact (contact: Contact): Observable<Contact> {
return this.http.post<Contact>(this.contactsUrl, contact, httpOptions).pipe(
tap((contact: Contact) => {
this.log(`${contact.name} added to list`)
this.contactSource.next(contact) //<--say that contactObservable "change"
}),
catchError(this.handleError<Contact>('addContact'))
);
}
}
然后,你的contacts-item.component描述了observable
export class ContactItemComponent implements OnInit {
contacts: Contact[] = [];
constructor(private contactService: ContactService) { }
ngOnInit(){
console.log("init");
this.getContacts();
this.subscribeChange();
}
getContacts(): void {
this.contactService.getContacts().subscribe(contacts => this.contacts = contacts);
}
subscribeChange():void{
this.contactService.contactsObservable.subscribe(
contact=> this.contact.push(contact))
}
}
正如您所看到的,http.get是一个特殊的可观察的&#34;没有&#34;下一个&#34;改变
答案 1 :(得分:0)
您需要一种方法来将一个组件与其他组件进行通信。 解决方案可以是使用BehaviorSubject。以下是BehaviorSubject vs Observable?
的示例<强>的ContactService 强>
1)您需要创建将保留联系人最后一个值的BehaviorSubject。
private contacts: BehaviorSubject<Contact[]> = new BehaviorSubject<Contact[]>([]);
2)如果需要为联系人添加新值,则需要使用BehaviorSubject对象上的更新联系人调用下一个方法。
this.contacts.next(updatedContacts);
3)在 ContactItemComponent 中,您需要订阅BehaviorSubject联系人。当调用下一个方法时,您将获得更新的联系人
答案 2 :(得分:-1)