【问题标题】:How to share data between components using service and observable?如何使用 service 和 observable 在组件之间共享数据?
【发布时间】:2018-10-09 02:45:55
【问题描述】:

嗨,我是 Angular 2+ 的新手, 我试图在两个组件之间共享数据,但第二个组件没有从服务中检索数据,它得到一个空对象。

Service - 使用 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 数据。我不确定我在这里做错了什么?

谢谢

【问题讨论】:

    标签: angular rxjs observable angular-services behaviorsubject


    【解决方案1】:

    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);
        });
      }
    

    3re 方法是使用 getter

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

    【讨论】:

    • 很好的答案!如果我理解正确的话,我认为#1和#2是在第一个和第二个代码块中切换的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    • 2020-08-31
    • 2021-10-12
    • 1970-01-01
    相关资源
    最近更新 更多