Angular Observable不更新内容

时间:2018-04-14 08:29:10

标签: angular observable angular2-forms

我有角度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);
        })
  }

3 个答案:

答案 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)

您需要从contact-add.component.ts发出事件,以便您的contact-item.component.ts可以触发getContacts()以接收新的更新联系人列表。

有关组件互动的更多信息,您可以找到image