我正在用Typescript构建Angular2应用程序,并希望使用Typescript提供的类系统功能(读:类继承).然而,Angular2似乎并没有很好地处理派生类.我正在寻求一些帮助,以使我的申请工作.

我面临的问题是,我有一个基类,并从中派生出几个子类.当我建立组件树时,我希望能够访问组件的父/子级(任何一种方式都可以).据我所知,Angular2提供了两个选项来实现这一点:

  1. 将父组件注入子组件
  2. 使用ContentChildren(或ViewChildren)访问组件的子项.

如果您知道正在使用的类的类型(ChildComponent),这两种方法都可以很好地工作,但是当您try 使用这些组件的基类(BaseComponent)作为 Select 器时,这两种方法似乎都失败了.

为了在一些代码中可视化它(请参阅这Plunker的实时演示),我有一个应用程序组件/类,如下所示:

@Component({
  selector: 'my-app',
  template: `<parent-comp>
      <child-comp1></child-comp1>
      <child-comp1></child-comp1>
      <child-comp2></child-comp2>
    </parent-comp>`,
  directives: [ParentComponent, ChildComponent1, ChildComponent2]
})
export class MyApplication  {
}

基类和子类定义为:

export class BaseComponent {
  // Interesting stuff here
}

@Component({
  selector: 'child-comp2',
  template: '<div>child component #2</div>'
})
export class ChildComponent2 extends BaseComponent {
}

@Component({
  selector: 'child-comp1',
  template: '<div>child component #1</div>'
})
export class ChildComponent1 extends BaseComponent {
}

父类有一些逻辑来计算它的子类.

@Component({
  selector: 'parent-comp',
  template: `<div>Hello World</div>
   <p>Number of Child Component 1 items: {{numComp1}}
   <p>Number of Child Component 2 items: {{numComp2}}
   <p>Number of Base Component items: {{numBase}}
   <p><ng-content></ng-content>
  `
})
export class ParentComponent implements AfterContentChecked  {

  @ContentChildren(ChildComponent1) contentChild1: QueryList<ChildComponent1>
  @ContentChildren(ChildComponent2) contentChild2: QueryList<ChildComponent2>
  @ContentChildren(BaseComponent) contentBase: QueryList<BaseComponent>
  public numComp1:number
  public numComp2:number
  public numBase:number

  ngAfterContentChecked() {
    this.numComp1 = this.contentChild1.length
    this.numComp2 = this.contentChild2.length
    this.numBase = this.contentBase.length
  }

(同样,您可以看到现场演示here)

前两个计数器的输出与预期一致.有2个ChildComponent1和1个ChildComponent2子项.不幸的是,BaseComponent计数器没有显示这些计数器的总和,而是显示0.它在子级中找不到任何BaseComponent类型的类.

当ParentComponent也从BaseComponent扩展,并且您希望将其注入ChildComponent时,也会发生同样的事情.Injector将需要特定类型的ParentComponent,并且不能与基类一起使用.

关于如何在Angular2中使用派生类有什么线索吗?我是不是错过了什么或者try 了什么不可能的事?

推荐答案

for each 衍生组件添加一个提供程序,将基础组件别名为衍生组件:

@Component({
  selector: 'child-comp2',
  template: '<div>child component #2</div>',
  providers: [{provide: BaseComponent, useExisting: forwardRef(() => ChildComponent2) }]
})
export class ChildComponent2 extends BaseComponent {
}

@Component({
  selector: 'child-comp1',
  template: '<div>child component #1</div>',
  providers: [{provide: BaseComponent, useExisting: forwardRef(() => ChildComponent1) }]
})
export class ChildComponent1 extends BaseComponent {
}

普朗克:http://plnkr.co/edit/5gb5E4curAE2EfH2lNZQ?p=preview

Angular相关问答推荐

如何从Angular TS文件传递$Events对象?

导致无限请求的Angular HttpInterceptor和HttpClientModule

对子router-outlet 应用主机样式

我们应该在Angular 从14升级到15的过程中也升级茉莉花和业力相关的依赖吗?

如何防止打印后的空格后的HTML元素的Angular ?

Angular 16+使用ngTemplateOutlet有条件地呈现几个模板中的一个

Angular NG5002错误无效的ICU消息和意外字符EOF

根据最后发出的 observable 创建一个 observable

PrimeNG:如何以编程方式更改分页器中的选定页面?

如何有条件地更新 Angular 路由解析器数据?

如何在Cypress 测试中切换 Angular 选项卡

Angular 无法从后端获取数据到前端

为什么 Redux 中的对象应该是不可变的?

将查询参数附加到 URL

Angular:ViewChild 上未定义 nativeElement

Angular-CLI 代理到后端不起作用

使用 Angular 2 新路由更改页面标题

移除 Angular 组件创建的宿主 HTML 元素 Select 器

@HostBinding 与 Angular 中的变量类

declarations和entryComponents组件有什么区别