gpt4 book ai didi

javascript - 在此 Angular 2 应用程序中,此跨组件通信 "pattern"究竟如何工作?

转载 作者:行者123 更新时间:2023-11-30 11:32:58 25 4
gpt4 key购买 nike

我是 Angular 2 的新手,我对这种使用服务的跨组件通信究竟是如何工作的有疑问。

在我的应用程序中,我有这个 RecipeService 服务类:

@Injectable()
export class RecipeService {

// Hold a Recipe object to be emitted to another component to implement cross component comunication:
recipeSelected = new EventEmitter<Recipe>();

// List of all recipes (maybe later can be obtained by a web service)
private recipes: Recipe[] = [
new Recipe(
'Tasty Schnitzel',
'A super-tasty Schnitzel - just awesome!',
'https://upload.wikimedia.org/wikipedia/commons/7/72/Schnitzel.JPG',
[
new Ingredient('Meat', 1),
new Ingredient('French Fries', 20)
]),
new Recipe('Big Fat Burger',
'What else you need to say?',
'https://upload.wikimedia.org/wikipedia/commons/b/be/Burger_King_Angus_Bacon_%26_Cheese_Steak_Burger.jpg',
[
new Ingredient('Buns', 2),
new Ingredient('Meat', 1)
])
];

// Inject a sub service:
constructor(private slService: ShoppingListService) {}

/**
* Return a copy of the reipes array.
* @returns {Recipe[]}
*/
getRecipes() {
return this.recipes.slice();
}

addIngredientsToShoppingList(ingredients: Ingredient[]) {
this.slService.addIngredients(ingredients);
}
}

这个类被两个不同的组件使用来实现这个发射器的跨组件通信:

recipeSelected = new EventEmitter<Recipe>();

根据我的理解(如果我做错了断言,请纠正我)这个 recipeSelected 发出的事件保存包含在 Recipe 对象中的信息(它包含一些字符串字段)。

然后我有这个 RecipeItemComponent 组件(它代表一个食谱,它的 View 显示与特定食谱相关的信息):

@Component({
selector: 'app-recipe-item',
templateUrl: './recipe-item.component.html',
styleUrls: ['./recipe-item.component.css']
})
export class RecipeItemComponent implements OnInit {
@Input() recipe: Recipe;

// Inkect the RecipeService to use it in this component:
constructor(private recipeService: RecipeService) { }

ngOnInit() {
}

/**
* When a specific recipe is selected in the page it emit the selected recipe to comunicate
* with another component
*/
onSelected() {
this.recipeService.recipeSelected.emit(this.recipe);
}

}

当用户单击链接进入与此 RecipeItemComponent 相关的 View 时,将执行此类的 onSelected() 方法。

据我所知,它只是发出与此 Recipe 对象相关的事件。所以我认为它是将这个对象的内容拍摄给其他人,而其他人应该是另一个组件(因此它实现了跨组件通信概念)。

然后我有另一个 RecipesComponent 组件类:

@Component({
selector: 'app-recipes',
templateUrl: './recipes.component.html',
styleUrls: ['./recipes.component.css'],
providers: [RecipeService]
})
export class RecipesComponent implements OnInit {
selectedRecipe: Recipe;

/**
* Inject the RecupeService to use it in this component
* @param recipeService
*/
constructor(private recipeService: RecipeService) { }

/**
* Subscribe on the event emitted when a recipe is selected:
*/
ngOnInit() {
this.recipeService.recipeSelected
.subscribe(
(recipe: Recipe) => {
this.selectedRecipe = recipe;
}
);
}

}

据我所知,我正在将此类事件的“监听器”(它是监听器吗?)注册到 ngOnInit() 方法中,方法是:

  ngOnInit() {
this.recipeService.recipeSelected
.subscribe(
(recipe: Recipe) => {
this.selectedRecipe = recipe;
}
);
}

因此,在实践中,每次 RecipeItemComponent 组件发出包含 Recipe 对象的事件时,该信息都会被 RecipesComponent 接收使用它的组件。是吗?

然后我对这个语法有疑问:

(recipe: Recipe) => {
this.selectedRecipe = recipe;
}

具体是什么意思?我认为 recipe: Recipe 是接收到的事件的内容。这有点像声明函数的隐式方式? (我来自 Java,我不太喜欢这种语法)。

另一个疑惑是:为什么这段代码要声明到ngOnInit()中?我的想法是,它在创建此组件时声明一个监听器,然后此监听器对可能第二次出现的事件使用react。是吗?

最佳答案

EventEmitter 不应在服务中使用。

查看这篇文章:What is the proper use of an EventEmitter?

来自那个帖子:

Use by directives and components to emit custom Events.

不得用于服务。正如@Pablo 提到的,即使对于组件,也建议您使用@O​​utput 来公开您的事件。

对于服务,通常 Angular 的变化检测会处理服务数据的变化。因此,您需要做的就是公开该数据。我这里有一个例子:

https://blogs.msmvps.com/deborahk/build-a-simple-angular-service-to-share-data/

这里有一个相应的插件:https://plnkr.co/edit/KT4JLmpcwGBM2xdZQeI9?p=preview

import { Injectable } from '@angular/core';

@Injectable()
export class DataService {
serviceData: string;
}

所以这样:

@Injectable()
export class RecipeService {

recipeSelected = new EventEmitter<Recipe>();

变成这样:

@Injectable()
export class RecipeService {

recipeSelected: Recipe;

还有这个:

  onSelected() {
this.recipeService.recipeSelected.emit(this.recipe);
}

变成这样:

  onSelected() {
this.recipeService.recipeSelected=this.recipe;
}

还有这个:

export class RecipesComponent implements OnInit {
selectedRecipe: Recipe;

ngOnInit() {
this.recipeService.recipeSelected
.subscribe(
(recipe: Recipe) => {
this.selectedRecipe = recipe;
}
);
}

}

变成这样:

export class RecipesComponent implements OnInit {
get selectedRecipe(): Recipe {
return this.recipeService.recipeSelected;
};
}

每次 recipeSelected 更改时,都会通知 Angular 更改检测,并且 UI 会重新绑定(bind)到 selectedRecipe 的当前值。

关于javascript - 在此 Angular 2 应用程序中,此跨组件通信 "pattern"究竟如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45594930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com