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" 可以更改