Angular Observable 不更新内容
Angular Observable not updating content
我在angular4中有两个组件和一个服务,组件一添加联系人,组件二显示联系人。我正在使用 HttpClient 和 Observables 来获取所有联系人,但是当我添加一个联系人时,我的第二个组件没有更新联系人。我通过 service.The 联系人在开始时显示良好但是当我触发 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'))
);
}
}
我的联系人-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);
}
}
我的联系人-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);
})
}
您需要从您的联系人-add.component.ts 发出事件,以便您的联系人-item.component.ts 可以触发 getContacts() 以接收新的更新联系人列表。
您可以找到有关组件交互的更多信息here
您需要一种方式让一个组件与另一个组件通信。
解决方案可以是使用 BehaviorSubject。这是一个例子
联系服务
1) 您需要创建 BehaviorSubject 来保留联系人的最后一个值。
private contacts: BehaviorSubject<Contact[]> = new BehaviorSubject<Contact[]>([]);
2) 如果需要向联系人添加新值,需要调用 下一个方法 更新 BehaviorSubject 对象上的联系人。
this.contacts.next(updatedContacts);
3) 在 ContactItemComponent 中,您需要订阅 BehaviorSubject 联系人。当调用下一个方法时,您将获得更新的联系人
Sergio,当你添加一个"contact"时,你做了:1)在dbs中添加联系人,2.-将联系人添加到contact-add.component中的数组联系人中,没有别的.您必须"something more"联系-item.component考虑变化。
当我们订阅 contactService.getContact() 时,只订阅一次 "getContact"。
解决方案:
1.- 服务存储联系人,我们使用 getter 到 get/set 值
在您的联系人服务中
@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> {
...
}
}
那么,您可以在您的联系人中-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 组件中
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.-按照 Andrey 的指示在您的服务中订阅 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'))
);
}
}
然后,您的联系人-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 是一个 "special observable",没有 "next" 可以更改
我在angular4中有两个组件和一个服务,组件一添加联系人,组件二显示联系人。我正在使用 HttpClient 和 Observables 来获取所有联系人,但是当我添加一个联系人时,我的第二个组件没有更新联系人。我通过 service.The 联系人在开始时显示良好但是当我触发 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'))
);
}
}
我的联系人-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);
}
}
我的联系人-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);
})
}
您需要从您的联系人-add.component.ts 发出事件,以便您的联系人-item.component.ts 可以触发 getContacts() 以接收新的更新联系人列表。
您可以找到有关组件交互的更多信息here
您需要一种方式让一个组件与另一个组件通信。
解决方案可以是使用 BehaviorSubject。这是一个例子
联系服务
1) 您需要创建 BehaviorSubject 来保留联系人的最后一个值。
private contacts: BehaviorSubject<Contact[]> = new BehaviorSubject<Contact[]>([]);
2) 如果需要向联系人添加新值,需要调用 下一个方法 更新 BehaviorSubject 对象上的联系人。
this.contacts.next(updatedContacts);
3) 在 ContactItemComponent 中,您需要订阅 BehaviorSubject 联系人。当调用下一个方法时,您将获得更新的联系人
Sergio,当你添加一个"contact"时,你做了:1)在dbs中添加联系人,2.-将联系人添加到contact-add.component中的数组联系人中,没有别的.您必须"something more"联系-item.component考虑变化。
当我们订阅 contactService.getContact() 时,只订阅一次 "getContact"。
解决方案:
1.- 服务存储联系人,我们使用 getter 到 get/set 值 在您的联系人服务中
@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> {
...
}
}
那么,您可以在您的联系人中-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 组件中
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.-按照 Andrey 的指示在您的服务中订阅 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'))
);
}
}
然后,您的联系人-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 是一个 "special observable",没有 "next" 可以更改