Angular 无法从rxjs observable中提取数据

Angular 无法从rxjs observable中提取数据,angular,typescript,service,rxjs,observable,Angular,Typescript,Service,Rxjs,Observable,我有一个服务,提供一个可观察的“配方”集合 @Injectable({ providedIn: 'root' }) export class RecipeService { recipes: Recipe[]; private _recipesSource = new Subject<Recipe[]>(); recipesMessage$ = this._recipesSource.asObservable(); constructor() { th

我有一个服务,提供一个可观察的“配方”集合

@Injectable({
  providedIn: 'root'
})
export class RecipeService {

  recipes: Recipe[];
  private _recipesSource = new Subject<Recipe[]>();
  recipesMessage$ = this._recipesSource.asObservable();

  constructor() {
    this.recipes = new Array<Recipe>();
    this.recipes.push(new Recipe('Recipe1', 1));
    this.recipes.push(new Recipe('Recipe2', 2));
    this.recipes.push(new Recipe('Recipe3', 3));
    this._recipesSource.next(this.recipes);
  }
}
我遇到的问题是,当页面被送达时,按钮没有出现。我的订阅似乎没有返回任何内容


如果我的打字稿不好,请原谅我。我是Javascript领域的新手,欢迎反馈。

这是因为角度变化检测无法捕捉到变化,因为它在aync订阅调用中发生了变化

替换

*ngFor=“让配方中的配方”

*ngFor=“let recipe of rs.recipesMessage$| async”

您可以删除

loadRecipes(): void {
    this.rs.recipesMessage$
      .subscribe(
        recipes => this.recipes = recipes
      );
  }
以及


ngOnInit中的
this.loadRecipes()

这是因为
recipes
变化不会被角度变化检测捕获,因为它在aync订阅调用中发生了变异

替换

*ngFor=“让配方中的配方”

*ngFor=“let recipe of rs.recipesMessage$| async”

您可以删除

loadRecipes(): void {
    this.rs.recipesMessage$
      .subscribe(
        recipes => this.recipes = recipes
      );
  }
以及


ngOnInit中的
this.loadRecipes()

不起作用,因为您使用
Subject
并在
构造函数中向其传递值

因为
Subject
本身是一个热可观察的对象,当您将值推给它时,它会立即发出它们,所以在您的情况下,当Angular为您的
RecipeService
运行
constructor
函数时。但当时,
RecipeListComponent
的模板还没有准备好,所以
| async
还没有启动

通常,在这些场景中,会使用行为主体。它将最后发出的值保留给延迟订阅服务器:

private _recipesSource = new BehaviorSubject<Recipe[]>([]);
private\u recipesource=新的行为主体([]);

这不起作用,因为您使用
主题
并在
构造函数中向其传递值

因为
Subject
本身是一个热可观察的对象,当您将值推给它时,它会立即发出它们,所以在您的情况下,当Angular为您的
RecipeService
运行
constructor
函数时。但当时,
RecipeListComponent
的模板还没有准备好,所以
| async
还没有启动

通常,在这些场景中,会使用行为主体。它将最后发出的值保留给延迟订阅服务器:

private _recipesSource = new BehaviorSubject<Recipe[]>([]);
private\u recipesource=新的行为主体([]);

您可以创建stackblitz吗?我猜你的代码是绝对好的,它应该工作你能创建一个stackblitz吗?我想你的代码是绝对好的,应该在这里提供一些高质量的建议,但它仍然不起作用(有问题的代码已经更新)。我将发布一个更完整的stackblitz。当然,我将根据您完整的stackblitz修改我对stackblitz链接的回答。或者尝试在
RecipeListComponent
constructor:
public rs:RecipeService
中公开rs注入,这里肯定有一些高质量的建议,但仍然不起作用(有问题的代码已更新)。我将发布一个更完整的stackblitz。当然,我将根据您完整的stackblitz修改我对stackblitz链接的回答。或者尝试在
RecipeListComponent
constructor:
public rs:RecipesService
中公开rs注入。谢谢只是好奇-有没有一个我应该选择使用的首选模式或生命周期挂钩?我使用这个,我看到的其他开发人员也使用这个。所以我认为这是一种首选模式。不用担心这里的时间安排。在Angular的服务中没有这样做的钩子。谢谢只是好奇-有没有一个我应该选择使用的首选模式或生命周期挂钩?我使用这个,我看到的其他开发人员也使用这个。所以我认为这是一种首选模式。不用担心这里的时间安排。在服务中没有挂钩