包装具有父/子关系的Angular组件

问题描述 投票:2回答:1

我试图用我自己的组件包装一些第三方组件(所有这些组件都是Angular 5组件)。

当使用第三方组件(没有包装它们)时,我有以下代码:

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

我的目标是将这些组件包装成以下代码:

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

这是我编写包装组件的方式(xyz-menubar包装到app-menu中):

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

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

并将xyzMenubarItem包装到app-menu-item中:

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

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

主要问题是第三方xyzMenubarItem组件依赖于xyzMenubar(其父级),如下所示:

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

当我尝试使用我的包装组件(app-menu和app-menu-item,如开头所述)时,我收到以下错误:

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)

我应该如何包装具有子/父依赖关系的第三方组件?

angular dependency-injection components parent-child
1个回答
0
投票

您可以通过在自定义MenuBarComponent组件上提供app-menu来解决此问题:

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

© www.soinside.com 2019 - 2024. All rights reserved.