@Input和其他装饰器和继承

时间:2016-02-25 15:03:00

标签: angular angular2-inputs

我真的不明白对象绑定是如何工作的,所以如果有人能解释我是否可以在基类中使用@Input(),或者更好:装饰器和继承。  例如,如果每个表单都应该接收一个客户我有一个基类:

export class AbstractCustomerForm{

@Input() customer;
...
}

然后我在实际组件中扩展此类:

export AwesomeCustomerForm extends AbstractCustomerForm implements OnInit{
    ngOnInit(){

        if(this.customer)
            doSomething();

    }
}

但这不起作用,客户永远不会被设置:(

6 个答案:

答案 0 :(得分:8)

<强>更新

2.3.0-rc.0

以来,

正确支持继承

<强>原始

装饰器不是继承的。它们需要直接应用于用作组件的类。子类上的装饰器将被忽略。我已经看到它提到@Input()@Output()正在工作,如果只有超类有它们而且子类没有。

答案 1 :(得分:5)

我遵循的一个策略是这样的:

@Component({
    selector: 'my-component',
    template: `......`,
    inputs: MyAbstractComponent.genericInputs
})
export class MyComponent extends MyAbstractComponent {

    @Input() width: number = 200;
    ........
}

其中:

export abstract class MyAbstractComponent {
    public static genericInputs : string[] = ['base'];
    public base: String;
}

因此,MyComponent将获得base以及width绑定。事实上,我认为使用反思仍有改进的余地。

答案 2 :(得分:3)

即使在Angular 4.2.4中,它在开发模式下也能正常工作。但是当做prod构建(ng build -prod)时,它失败了:

ERROR in Template parse errors:
Can't bind to 'step' since it isn't a known property of 'app-textarea-step'.
1. If 'app-textarea-step' is an Angular component and it has 'step' input, 
then verify that it is part of this module.
2. If 'app-textarea-step' is a Web Component then add 
'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to 
suppress this message.

我的组件如下:

abstract class StepComponent {
  @Input() step: BaseStep;
  @Output() next = new EventEmitter<string>();
  @Output() answer = new EventEmitter<Answer>();
}

abstract class SingleNextStepComponent extends StepComponent {

  onSubmit(answer: string) {
    // ConfirmStep heeft geen answer.
    if (answer) {
      this.answer.emit({ question: this.step.key, value: answer });
    }
    const step = this.step as SingleNextStep;
    this.next.emit(step.next);
  }
}

// Decorator inheritance works in standard build (ng build) but fails in production build (ng build -prod)
// Workaround: inputs element on @Component that contains the inputs.....
@Component({
  selector: 'app-textbox-step',
  templateUrl: './textbox-step.component.html',
  inputs: ['step']
})
export class TextboxStepComponent extends SingleNextStepComponent { }

@Component({
  selector: 'app-textarea-step',
  templateUrl: './textarea-step.component.html',
})
export class TextareaStepComponent extends SingleNextStepComponent { }

幸运的是,解决方法有效。添加到TextBoxStepComponent的输入已经阻止了这个输入失败,直到下一个输入,还没有提供&#39;输入&#39;。

但是&#39; ng build&#39;工作正常,无需@Component装饰器上的输入......

答案 3 :(得分:1)

我在这里找到了一个可能的解决方案:

https://medium.com/@ttemplier/angular2-decorators-and-class-inheritance-905921dbd1b7#.ca68alvcz

基本上,它创建了一个自定义装饰器,它只是通过反射合并父装饰和子装饰器。

实际上,我并没有让它适用于基于angular-cli的项目。

答案 4 :(得分:0)

装饰器不是继承的,而是类。所以我的解决方案是:

bodyBuilder.HtmlBody = (load msg.html)

答案 5 :(得分:0)

我遇到了这个问题,并且只是想指出,从Angular 2.3.0-rc.0开始,这实际上是可能的。

  

继承语义:

     

装修:

     

1)在祖先的第一个订单中列出类及其父类的装饰器

     

2)只使用各种最后一个装饰器(例如@Component / ...)

     

构造函数参数:

     

如果某个类继承自父类但未声明   一个构造函数,它继承父类构造函数,   并使用该父类的参数元数据。

     

生命周期钩子:

     

遵循普通的类继承模型,   即将调用父类的生命周期钩子   即使该方法没有在子类中被覆盖。

https://github.com/angular/angular/commit/f5c8e09