我想在ngOnInit(){}的第二个方法中的一个方法中使用.subscribe的结果

时间:2019-07-17 17:26:34

标签: angular observable subscribe ngoninit

我有一种使用服务来获取书籍列表的方法,我需要第二种方法来使用书籍列表通过按ID过滤来获取书籍。这两个方法在同一组件的“ ngOnInit”中调用。我在第二种方法中得到的是在获得结果之前使用图书清单。

我通过在.subscribe结果内部的第一个中调用第二个方法,然后仅在ngOnInit中调用第一个方法来解决此问题。我没有找到令人满意的解决方案,我想要一种更通用,更有条理的方式...

import requests
from requests.auth import HTTPProxyAuth

response = requests.post(url_base, data = url_options, auth = HTTPProxyAuth("username", "password"))

这是我得到的错误:

export class BookComponent implements OnInit {
  public books: Book[];
  public book: Book;
  public id;
  public sub;

  constructor(private activatedRoute: ActivatedRoute, private router: Router, private bookService: BookService) {}
  getBooks() {
    this.bookService.getBooks().subscribe(
      result => {
        this.books = result;
      }
    );
  }

  findById() {
    this.sub = this.activatedRoute.paramMap.subscribe(params => {
      console.log(params);
      this.id = params.get('id');
      this.book = this.books.find(a => a.id == this.id);
    });
  }


  ngOnInit() {
    this.getbooks();
    this.findById();
  }
}

3 个答案:

答案 0 :(得分:0)

尝试一下

findById() {
this.sub = this.activatedRoute.paramMap.subscribe(params => {
  console.log(params);
  this.id = params.get('id');
  this.book = this.books.find(a => a.id == this.id);
});
}


ngOnInit() {
  this.books = [];
  this.getbooks();
  this.findById();
}

答案 1 :(得分:0)

之所以发生这种情况,是因为书没有初始化。由于您同时运行两个异步函数,因此无法保证在调用books之前getBooks()的内容已由findById()初始化。

您可以通过将对findById()的调用放在getBooks()的调用中来避免此问题。这种情况会导致订阅地狱(多个嵌套订阅),但是可以使用rxjs清除该问题。

相应地在下面重新排列原始代码。

export class BookComponent implements OnInit {
  public books: Book[];
  public book: Book;
  public id;
  public sub;

  constructor(private activatedRoute: ActivatedRoute, private router: Router, private bookService: BookService) {}
  ngOnInit() {
    this.getbooks();
  }

  getBooks() {
    this.bookService.getBooks().subscribe(
      result => {
        this.books = result;
        this.findById()
      }
    );
  }

  findById() {
    this.sub = this.activatedRoute.paramMap.subscribe(params => {
      console.log(params);
      this.id = params.get('id');
      this.book = this.books.find(a => a.id == this.id);
    });
  }

}

答案 2 :(得分:0)

您的直觉是正确的,您不应尝试在订阅内部调用订阅...您应该使用更高阶的可观察对象来实现此目标,并确保在需要的地方获得所有可观察数据。在这种情况下,您要使用CombineLatest:

ngOnInit() {
  this.sub = combineLatest(this.bookService.getBooks(), this.activatedRoute.paramMap)
               .subscribe(([books, params]) => }
                 this.books = books;
                 this.id = params.get('id');
                 this.book = this.books.find(a => a.id == this.id);
               });
}

现在,订阅回调将在每次可观察到的流发出时都运行,但只有一次,两者都发出了至少一次。无需其余。在这种情况下,我假设getBooks()只会发出一次,但是如果用户导航到另一个书本ID,则paramMap可能会再次发出。