@Input and other decorators and inheritance

泄露秘密 提交于 2020-01-11 08:19:10

问题


I don't really understand how object binding works, so if anyone could explain if I can use @Input() inside a base class, or better: decorators and inheritance. For example if each form should receive a customer I have a base class:

export class AbstractCustomerForm{

@Input() customer;
...
}

and then I extend this class in an actual component:

export AwesomeCustomerForm extends AbstractCustomerForm implements OnInit{
    ngOnInit(){

        if(this.customer)
            doSomething();

    }
}

but this won't work, customer will never get set :(


回答1:


update

Inheritance is properly supported since 2.3.0-rc.0

original

Decorators are not inherited. They need to be applied to the class used as component directly. Decorators on subclasses are ignored. I have seen it mentioned that @Input() or @Output() are working if only the super class has them and the sub-class has none.

  • https://github.com/angular/angular/issues/5794
  • https://github.com/angular/angular/issues/5415
  • https://github.com/angular/angular/issues/7191



回答2:


One strategy that I am following is something like this:

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

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

where:

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

therefore, MyComponent would get base as well as width bindings. In fact, I think there is still room for improvement by using reflection.




回答3:


Even in Angular 4.2.4 it works fine in dev mode. But when doing a prod build (ng build -prod) it fails:

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.

My component looks like:

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 { }

Fortunately the workaround works. The inputs a added to the TextBoxStepComponent have prevented this one to fail, falling through to the next one, not yet provided with 'inputs'.

But 'ng build' works fine without needing inputs on the @Component decorators...




回答4:


I found a possible solution here:

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

Basically, it creates a custom Decorator that simply merges parent and child decorators through reflection.

Actually I coudn't make it work on projects baseed on angular-cli.




回答5:


Decorators are not inherited, but class are. So my solution was this:

@Component({selector: 'a')
class A {
  @Input() field;
}

@Component({selector: 'b', inputs: ['field']}
class B extends A {
}



回答6:


I came across this question, and just wanted to point out that as of Angular 2.3.0-rc.0 this is actually possible.

Inheritance Semantics:

Decorators:

1) list the decorators of the class and its parents in the ancestor first order

2) only use the last decorator of each kind (e.g. @Component / ...)

Constructor parameters:

If a class inherits from a parent class and does not declare a constructor, it inherits the parent class constructor, and with it the parameter metadata of that parent class.

Lifecycle hooks:

Follow the normal class inheritance model, i.e. lifecycle hooks of parent classes will be called even if the method is not overwritten in the child class.

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



来源:https://stackoverflow.com/questions/35630947/input-and-other-decorators-and-inheritance

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