Как обмениваться данными между компонентами, используя сервис и наблюдаемый? - PullRequest
0 голосов
/ 28 апреля 2018

Привет, я новичок в угловой 2+, Я пытаюсь обмениваться данными между двумя компонентами, но второй компонент не получает данные из службы, он получает пустой объект.

Сервис - использование rxjs BehaviorSubject для сохранения объекта

import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class PostsService {

  response: any = {};
  private messageResponse = new BehaviorSubject(this.response);
  currentResponse = this.messageResponse.asObservable();

  constructor(private http: Http) { }

  // Get all posts from the API
  getAllPosts() {
    return this.http.get('/api/posts')
      .map(res => {
         this.messageResponse.next(res.json());
         return res.json();
      }).catch(err => {
         console.log('caught exception' + err.status);
         return Observable.throw(err);
      });
  }
}

Компонент 1 - Посты. Этот компонент делает первый вызов, чтобы получить данные, и без проблем извлекается и обновляет messageResponse.

export class PostsComponent implements OnInit {
  // instantiate posts to an empty array
  posts: any = [];

  constructor(private postsService: PostsService) { }

  ngOnInit() {
    // Retrieve posts from the API
    this.postsService.getAllPosts().subscribe(posts => {
      this.posts = posts;
    });
  }
}

Компонент 2 - Сообщения 2 - Этот компонент получает currentResponse, однако в журнале отображается пустой массив.

export class Posts2Component implements OnInit {
  posts: any = [];

  constructor(private postsService: PostsService) { }

  ngOnInit() {
    this.postsService.currentResponse.subscribe(posts => {
      this.posts = posts;
      console.log(this.posts);
    });
  }
}

Всякий раз, когда я просматриваю компонент Posts2, я не вижу никаких данных currentResponse. Я не уверен, что я сделал не так здесь?

Спасибо

1 Ответ

0 голосов
/ 28 апреля 2018

User3511041, только если вы подписываетесь на Observable, то observable выполняется. В сервисе мы можем использовать три подхода. (Я использую httpClient, а не «старый» и «устаревший» http)

@Injectable()
export class PostsService {

  response: any = {};
  private messageResponse = new BehaviorSubject(this.response);
  currentResponse = this.messageResponse.asObservable();

  constructor(private httpClient: Http) { }

  // 1.-Return and observable 
  getAllPosts():Observable<any> {  //see that using httpClient we needn't json()
    return this.http.get('/api/posts').catch(err => {
         console.log('caught exception' + err.status);
         return Observable.throw(err);
      });

  // 2.- using next or  3.-fill an variable
  fillAllPosts():void {  
    this.http.get('/api/posts').catch(err => {
         console.log('caught exception' + err.status);
    }).subscribe(res=>{
          this.messsageResponse.next(res);  //<--(the 2nd approach)
          this.post=res;  //<--or using a variable (for the 3re approach)
    })
}

В компоненте вы можете подписаться на getAllPost () или на текущий Ответ

ngOnInit() {

    //1.-Subscribe to a currentResponse
    this.postsService.currentResponse.subscribe(posts => {
      this.posts = posts;
      console.log(this.posts);
    });
    // in this case we must call to fillAllPost after subscription
    this.postService.fillAllPost();

    //2.-Subscribe to a getAllPost()
    this.postsService.getAllPost().subscribe(posts => {
      this.posts = posts;
      console.log(this.posts);
    });
  }

3-й подход - использование геттера

  //a 3re approach is using a getter
  get post()
  { 
       return this.postService.post;
  }
  ngOnInit() {
       this.postService.fillAllPost()
  }
...