1

这个 plnker可能是查看问题的最快方法

我不确定在使用 ViewChild 时是否只是一些明显的问题,但这很奇怪。

plunker 显示 3 个输入:

  • 第一个输入是一个基本输入和一个可以聚焦它的按钮。
  • 第二个输入绑定到相同的值,单击编辑将解锁输入。
  • 第三个输入也绑定了相同的值,点击编辑将解锁输入并赋予它焦点。

但是,当添加 ViewChild 以获取对输入的引用时,输入上的 NgModel 绑定停止工作。但是您附加的任何其他绑定(如禁用)仍将继续起作用。如果您注释掉 app/extended.component 的第 52 行,它将再次绑定,但显然现在它无法聚焦。

第一个输入/按钮表明,这显然只是当您绑定到您正在扩展的类的属性时的问题。


简而言之,当我通过 ViewChild 访问输入时,我对 NgModel 的绑定会中断。

也就是说,给定一个具有属性“someValue”的基础: 绑定:

@Component({
  selector: 'binding-working',
  template: `<input type="text" [(ngModel)]="someValue" />`
})
export class Working extends Base<string> {  
  constructor() { }
};

不绑定:

@Component({
  selector: 'binding-broken',
  template: `<input type="text" #imBroken [(ngModel)]="someValue" />`
})
export class Broken extends Base<string> {  
  @ViewChild('imBroken') input;
  constructor() { }
};
4

1 回答 1

7

更新 2.3.0

好消息!

根据角度博客http://angularjs.blogspot.ru/2016/12/angular-230-now-available.html

开发人员现在可以利用组件的对象继承。通过从父组件继承来共享或简化组件功能。

那么它应该在没有自定义装饰器的情况下工作=> Plunker Example

您可以在此提交中看到更多详细信息https://github.com/angular/angular/commit/f5c8e0989d85bc064f689fc3595207dfb29413f4

旧版

就是这样设计的。

Angular2 不支持完全继承(https://github.com/angular/angular/issues/7968#issuecomment-219865739)。

您的子ViewChild装饰器覆盖propMetadata在基Extended类中定义。因此,您的ExtendedInputBroken班级没有父属性,例如baseLevelbaseLevelChange

Thierry Templier写了一篇关于 Angular2 中的类继承的精彩文章

如果您真的想这样做,我可以为您提供以下解决方案。

只需像这样创建自定义装饰器:

function InheritPropMetadata() {
  return (target: Function) => {
    const targetProps = Reflect.getMetadata('propMetadata', target);

    const parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    const parentProps = Reflect.getMetadata('propMetadata', parentTarget);

    const mergedProps = Object.assign(targetProps, parentProps);

    Reflect.defineMetadata('propMetadata', mergedProps, target);
  };
};

然后将其应用于您的ExtendedInputBroken班级:

@InheritPropMetadata()
export class ExtendedInputBroken extends Extended<string> implements OnInit {
  ...

Plunker 演示

此链接可能会让您感兴趣:

于 2016-07-02T05:21:32.600 回答