Wrapping Angular components which has Parent/Child relationship

╄→尐↘猪︶ㄣ 提交于 2020-06-27 12:22:41

问题


I'm trying to wrap some third-party components with my own components (All of them are Angular 5 components).

When using the third-party component (without wrapping them) I have the following code:

<div>
  <xyz-menubar>
    <a xyzMenubarItem></a>
    <a xyzMenubarItem></a>
  </xyz-menubar>
</div>

My goal is to wrap these components to have the following code:

<div>
  <app-menu>
    <app-menu-item></app-menu-item>
    <app-menu-item></app-menu-item>
  </app-menu>
</div>

This is how I coded the wrapped components (xyz-menubar wrapped into app-menu):

@Component({
  selector: 'app-menu',
  templateUrl: './menu.component.html'
})
export class MenuComponent {
}

<div>
  <xyz-menubar>
    <ng-content></ng-content>
  </xyz-menubar>
</div>

And xyzMenubarItem wrapped into app-menu-item:

@Component({
  selector: 'app-menu-item',
  templateUrl: './menu-item.component.html'
})
export class MenuItemComponent {
}

<a xyzMenubarItem>
  <ng-content></ng-content>
</a>

The main issue is that the 3rd party xyzMenubarItem component depends on xyzMenubar (its parent) as you can see below:

@Component({
  selector: 'xyz-menubar-item, [xyzMenubarItem]',
  template: `
      <ng-content></ng-content>
  `
})
export class MenubarItemComponent {
  constructor(protected menubar: MenubarComponent, protected _elementRef?: ElementRef) {}
}

When trying to use my wrapped components (app-menu and app-menu-item as described in the beginning), I get the following error:

ERROR Error: StaticInjectorError[MenubarComponent]: 
  StaticInjectorError[MenubarComponent]: 
    NullInjectorError: No provider for MenubarComponent!
    at _NullInjector.get (core.js:923)
    at resolveToken (core.js:1211)
    at tryResolveToken (core.js:1153)
    at StaticInjector.get (core.js:1024)
    at resolveToken (core.js:1211)
    at tryResolveToken (core.js:1153)
    at StaticInjector.get (core.js:1024)
    at resolveNgModuleDep (core.js:10585)
    at NgModuleRef_.get (core.js:11806)
    at resolveDep (core.js:12302)

How should I wrap these 3rd party components that has child/parent dependency?


回答1:


You can workaround it by providing MenuBarComponent on you custom app-menu component:

export function menuBarFactory(menu: MenuComponent) {
  return menu.menuBar;
}

@Component({
  selector: 'app-menu',
  template: `
    <div>
      <xyz-menubar>
        <ng-content></ng-content>
      </xyz-menubar>
    </div>
  `,
  providers: [
    { 
      provide: MenuBarComponent, 
      useFactory: menuBarFactory,
      deps: [MenuComponent]
    }
  ]
})
export class MenuComponent {
  @ViewChild(MenuBarComponent) menuBar: MenuBarComponent;
}

Stackblitz Example



来源:https://stackoverflow.com/questions/47550379/wrapping-angular-components-which-has-parent-child-relationship

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!