简体   繁体   English

同时打开同一个 angular 组件作为不同的实例

[英]Open same angular component as different instances at the same time

I have angular component that has a list with dataSource is subscribed from a BehaviourSubject from the service.我有一个 angular 组件,它有一个数据源列表,该组件是从服务的 BehaviourSubject 订阅的。

In the list.component.html template file:在 list.component.html 模板文件中:

<ng-container *ngFor="let item of items;">
    <h2>item.name</h2>
</ng-container>

In the list.component.ts file:在 list.component.ts 文件中:

ngOnInit(): void {
  this.service.items$.subscribe(data=>{
      this.items = data;
 });
}

On clicking the item in the list, it loads the sub items for the selected item in the same table.单击列表中的项目时,它会在同一个表中加载所选项目的子项目。

Now, I have a button side this component that will open a MatDialog window.现在,我在这个组件旁边有一个按钮,它将打开一个 MatDialog window。

This MatDialog windows should contain the same component mentioned above.这个 MatDialog windows 应该包含上述相同的组件。

What I have tried:我试过的:

I have created a wrapper for this component and opened the Wrapper in the MatDialog.我为这个组件创建了一个包装器,并在 MatDialog 中打开了包装器。

wrapper.component.html wrapper.component.html

<div>
 <app-list></app-list>
</div>

Inside list.component.html opening the WrapperComponent in MatDialog:里面 list.component.html 在 MatDialog 中打开 WrapperComponent:

this.matDialog.open(WrapperComponent);

Everything works fine until i click on the list item inside the matDialog.一切正常,直到我单击 matDialog 中的列表项。

The selected item is loaded isnide the list in the matDialog.所选项目在 matDialog 的列表中加载。 But at the same time in the background the orginal ListComponent is also loading the same value.但同时在后台原始 ListComponent 也在加载相同的值。 Becasue, the subscribed value from BehaviourSubject is updated when clicked on the item in the list.因为,当单击列表中的项目时,来自 BehaviourSubject 的订阅值会更新。

this.service.updateListValue = updatedValue;

The original ListComponent is loaded with router module and resolver.原始 ListComponent 加载了路由器模块和解析器。

How can i avoid this?我怎样才能避免这种情况? How to open the same component but as two different instances?如何打开相同的组件但作为两个不同的实例?

To inject a service class inside multiple modules as multiple instances:要将服务 class 作为多个实例注入到多个模块中:

what you can do this,你能做到这一点,

in your service class @Injectable为您服务 class @Injectable

Replace : @Injectable({ providedIn: 'root' })替换@Injectable({ providedIn: 'root' })

With : @Injectable({ providedIn: 'any' })@Injectable({ providedIn: 'any' })

When providedIn: 'root' option is used, the angular injector will make your service class act as a singleton and there will be only one instance of this service for the entire application.使用providedIn: 'root'选项时,angular 注入器将使您的服务 class 充当 singleton 的整个应用程序实例。

When providedIn: 'any' option is used, the Angular injector will instantiate a new service for each module that injects this service .providedIn: 'any'选项被使用时,Angular 注入器将为每个注入此服务的模块实例化一个新服务

Bonus: If a Class ServiceA is being used only by ModuleA, you can use奖励:如果 Class ServiceA 仅由 ModuleA 使用,您可以使用

@Injectable({ providedIn: ModuleA }) . @Injectable({ providedIn: ModuleA }) This will be optimal when you have a service that is being used only by Single module当您拥有仅由单个模块使用的服务时,这将是最佳选择

Reference: NG0201参考: NG0201

To inject a service class to multiple components inside the same module as multiple instances:要将服务 class 作为多个实例注入到同一模块内的多个组件中:

The answer by @misha130 could work too. @ misha130 的答案也可以。

In order to have a service specific for the component you need to provide it in the @Component decorator metadata.为了拥有特定于组件的服务,您需要在@Component装饰器元数据中提供它。 This will create an instance of the service for each component instance.这将为每个组件实例创建一个服务实例。

@Component({
    providers: [SomeService],
})

Your service should not be providedIn root as well.您的服务也不应该在 root 中providedIn

@Injectable()

If you want to use the same component and different metadata you can have 2 different service implementations based on the module.如果您想使用相同的组件和不同的元数据,您可以基于模块有 2 种不同的服务实现。

You can declare a token that would represent the service您可以声明一个代表服务的令牌

export const SERVICE_TOKEN: InjectionToken<SomeService> = new InjectionToken<SomeService>('Some Service Token');

Then in each module specify which service you want to inject:然后在每个模块中指定要注入的服务:

  providers: [
    {
      provide: SERVICE_TOKEN,
      useClass: SomeServiceA,
    },

Afterwards in the constructor of the component inject it like so:然后在组件的构造函数中像这样注入它:

   constructor(@Inject(SERVICE_TOKEN) private readonly someService: SomeService){}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM