Inject parent component of the same type as child component

前端 未结 3 1918
走了就别回头了
走了就别回头了 2020-12-14 23:22

In Angular 2, a child component can get its parent component injected through a constructor parameter. Example:

@Component({...})
export class ParentComponen         


        
相关标签:
3条回答
  • 2020-12-14 23:32

    This post has been solved thanks to Günther. However, I would like to follow up based on the architectural feedback I got.

    First and foremost: I completely agree that the TreeNodeComponent use case example is an anti pattern. A data driven component like a tree this should be controlled by data binding. My apologies for this anti pattern.

    However, my actual use case (which is more complex to explain) is that I want to develop an advanced dropdown menu. Requirements:

    • The dropdown should have arbitrary number of levels (menu, submenu, subsubmenu etc)
    • The dropdown is defined at design time - its content is not based on dynamic data.
    • It should be possible to attach event handlers (_)= to each dropdown item.
    • It should be possible to insert custom control components into the dropdown.

    A usage example:

    <dropdown label="Actions">
      <dropdown-item label="Action 1" (click)="action1()"></dropdown-item>
      <dropdown-item label="Action 2" (click)="action2()"></dropdown-item>
      <dropdown-item label="Submenu">
        <dropdown-item label="Action 3.1" (click)="action31()"></dropdown-item>
        <dropdown-item label="Action 3.2">
          <dropdown-slider (change)="changeHandler()"></dropdown-slider>
        </dropdown-item>
        <dropdown-item label="Submenu">
          <dropdown-item label="Action 3.3.1" (click)="action331()"></dropdown-item>
          <dropdown-item label="Action 3.3.2" (click)="action332()"></dropdown-item>
        </dropdown-item>  
      </dropdown-item>  
    </dropdown>    
    

    My consideration is that this would be hard to implement using data binding. It's much practical to be able to bind event handlers and include custom components this way.

    But I might be wrong! Any opinions about this are highly welcome!

    0 讨论(0)
  • 2020-12-14 23:48

    This way it's working

    constructor(@SkipSelf() @Host() @Optional() parent: TreeNodeComponent) {}
    

    Plunker

    • @SkipSelf() is to not get oneself injected which would apply if TreeNodeComponent is requested
    • @Host() don't look further up than the host element
    • @Optional() ?? there is no parent TreeNodeComponent for the root node

    See also http://blog.thoughtram.io/angular/2015/08/20/host-and-visibility-in-angular-2-dependency-injection.html

    0 讨论(0)
  • 2020-12-14 23:52

    Angular2 looks into the current injector for a provider. In your case, TreeNodeComponent corresponds to the component itself.

    The parent component instance is located into the parent injector.

    I think that you could try to inject an Injector class to have access to the parent injector and then get the instance of the parent component. Something like that:

    @Component({
      (...)
    })
    export class TreeNodeComponent {
      constructor(injector:Injector) {
        let parentInjector = injector.parent;
        let parent = patentInjector.get(TreeNodeComponent);
      }
    }
    

    See this link for the documentation of the Injector class:

    • https://angular.io/docs/ts/latest/api/core/Injector-class.html

    That said, I think that the Gunter's comment about binding and shared service is particularly relevant...

    0 讨论(0)
提交回复
热议问题