Angular - 从特定组件实例获取数据,以便能够通过单击按钮与之交互

Posted

技术标签:

【中文标题】Angular - 从特定组件实例获取数据,以便能够通过单击按钮与之交互【英文标题】:Angular - Get data from a particular component instance in order to be able to interact with it via a button click 【发布时间】:2021-11-01 18:39:30 【问题描述】:

我有一个状态框,它是它自己的组件。在我的应用中,这个状态框组件有多个实例,如下图所示:

每个状态框的详细信息存储在浏览器本地存储中,并在提交表单时创建,传入的表单值保存到浏览器本地存储并显示在状态框组件上。

每个单独的状态框组件实例的详细信息都被视为地图数据结构。当app.component 首次初始化时,会为存储在浏览器本地存储中的每个详细信息创建一个映射,并将它们推送到一个名为 myConfigs 的数组中:

export class AppComponent implements OnInit, OnDestroy

  myConfigs: any[] = [];
  localStorageKeys: string[] = ['Test']
  constructor() 
    
  ngOnInit(): void 
  
    for (var key of this.localStorageKeys)
      for(let i = 1; i < 5; i++)
        if (localStorage.getItem(key+i) != null)
          this.myConfigs.push(new Map(JSON.parse(localStorage.getItem(key+i)!)))
        else
          console.log(key+i + ' currently not available');
  

然后在 app.component 模板中,我们将 myConfigs 数组中的每个地图项作为单个配置进行循环,然后将其传递给指令 (appDynamicStatusBox)。

<app-header></app-header>
<div class='status-box-container'>
    <ng-container *ngFor="let config of myConfigs; let i=index" appDynamicStatusBox [config]="config"></ng-container>
</div>

在指令中,我们为每个状态框组件创建一个实例。 myConfigs 中的配置项是该指令中的 @Input,从那里我们可以通过 resolveComponentFactory 创建每个状态框组件,然后使用传入的配置变量设置该组件实例中的每个值:

@Directive(selector: '[appDynamicStatusBox]')

export class DynamicStatusBoxDirective implements OnInit

  @Input() config: any;
  componentRef!: ComponentRef<StatusBoxComponent>;

  constructor(private resolver: ComponentFactoryResolver, public viewContainerRef: ViewContainerRef) 

  ngOnInit(): void 
  
    const factory = this.resolver.resolveComponentFactory(StatusBoxComponent); // Retrieves the factory object that creates a component of the given type
    this.viewContainerRef.clear(); // clears the previous view
    this.componentRef = this.viewContainerRef.createComponent(factory); // Instantiates a single component of type StatusBoxComponent and inserts its host view into this container
    this.componentRef.instance.name = this.config.get('name')
    this.componentRef.instance.deviceId = this.config.get('device')
    this.componentRef.instance.cpuTemp = this.config.get('cpuTemp')
    this.componentRef.instance.diskUsage = this.config.get('diskSpace')
    this.componentRef.instance.systemUptime = this.config.get('uptime')
    this.componentRef.instance.systemTime = this.config.get('time')
    this.componentRef.instance.number = this.config.get('num')
    this.componentRef.instance.device = this.config.get('device')
    this.componentRef.instance.value = this.config.get('value')
  

我想做的是能够检索this.componentRef.instance.deviceId,它是存储在本地存储中的密钥,用于保存特定状态框组件的数据,并且能够按删除按钮删除本地存储,从而删除组件实例。

但我不确定如何通过单击/选择特定状态框组件的红色删除按钮来获取 this.componentRef.instance.deviceId 值。

如果有人可以提供帮助,将不胜感激。

【问题讨论】:

deviceId 是我猜的实际组件上的@input ..?因此,如果按钮是组件的一部分,则该 id 应该在范围内……对吧..? 【参考方案1】:

我会这样做:

创建状态服务 在创建时在每个组件中注入 StatusService(注意绑定父级和子级的注入器) 声明一个
private deleteSubject = new Subject<boolean>();
public delete$ = this.deleteSubject.asObservable()

public delete(checkboxId: string)
    this.deleteSubject.next(checkboxId);

从组件中您只需调用delete 从父母那里,您只需要听delete$ 就知道要删除哪个复选框。

更进一步,您可以完全管理服务中的复选框,并使您的父组件更加愚蠢:)


另一种方法是在你的指令上创建一个 Output()。并将其绑定到 Checkbox 中完全相同的 Output()

this.componentRef.instance.delete = this.delete

【讨论】:

我对 Angular 有点陌生,所以有些东西我不明白。我真的不知道我是否使用父子组件关系。据我了解,我只是通过指令创建了同一组件的多个实例。我也不确定 $ 在您的服务代码示例中意味着什么。我可以看到你的逻辑是如何工作的,但我需要更多的代码示例来完全掌握这个想法,因为我不确定该怎么做。谢谢。

以上是关于Angular - 从特定组件实例获取数据,以便能够通过单击按钮与之交互的主要内容,如果未能解决你的问题,请参考以下文章

如何从Angular中的另一个服务调用服务的特定实例?

Angular - 如何将数据从一个组件传递到另一个

Angular:从卡片路由到新视图

如何从 Angular 的弹性框中的组件中获取元素信息

如何从 ngOnInit Angular 中的服务获取数据

Angular 7 - 获取在 HTML 中声明的所有组件的组件实例