Я действительно не понимаю, как работает привязка объекта, поэтому, если кто-нибудь может объяснить, могу ли я использовать @Input () внутри базового класса или лучше: декораторы и наследование. Например, если каждая форма должна получать клиента, у меня есть базовый класс:

export class AbstractCustomerForm{

@Input() customer;
...
}

А затем я расширяю этот класс до фактического компонента:

export AwesomeCustomerForm extends AbstractCustomerForm implements OnInit{
    ngOnInit(){

        if(this.customer)
            doSomething();

    }
}

Но это не сработает, клиент никогда не настроится :(

13
Silencer 25 Фев 2016 в 18:03

6 ответов

Лучший ответ

обновить

Наследование правильно поддерживается, начиная с 2.3.0- rc.0

оригинал

Декораторы не наследуются. Их нужно напрямую применять к классу, используемому как компонент. Декораторы подклассов игнорируются. Я видел, как упоминалось, что @Input() или @Output() работают, если они есть только у суперкласса, а у подкласса их нет.

10
Günter Zöchbauer 26 Апр 2017 в 08:41

Я столкнулся с этим вопросом и просто хотел указать, что с Angular 2.3.0-rc.0 это действительно возможно.

Семантика наследования:

Декораторы:

1) перечислить декораторы класса и его родителей в порядке предка

2) используйте только последний декоратор каждого типа (например, @Component / ...)

Параметры конструктора:

Если класс наследуется от родительского класса и не объявляет конструктор, он наследует конструктор родительского класса, а вместе с ним и метаданные параметров этого родительского класса.

Крючки жизненного цикла:

Следуйте обычной модели наследования классов, то есть перехватчики жизненного цикла родительских классов будут вызываться, даже если метод не перезаписан в дочернем классе.

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

1
gamesmad 1 Фев 2017 в 11:57

Я нашел возможное решение здесь:

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

По сути, он создает собственный декоратор, который просто объединяет родительский и дочерний декораторы посредством отражения.

На самом деле я не мог заставить его работать на проектах, основанных на angular-cli.

1
Emilio Numazaki 5 Авг 2016 в 01:11

Одна стратегия, которой я следую, выглядит примерно так:

@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. На самом деле, я думаю, что есть еще возможности для улучшения с помощью отражения.

5
lqbweb 11 Сен 2016 в 23:25

Даже в Angular 4.2.4 он отлично работает в режиме разработки. Но при сборке продукта (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, предотвратили сбой этого компонента, переходя к следующему, еще не снабженному «входами».

Но 'ng build' отлично работает и не требует ввода в декораторах @Component ...

4
msanford 28 Июн 2017 в 20:18

Декораторы не наследуются, но класс наследуется. Итак, мое решение было таким:

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

@Component({selector: 'b', inputs: ['field']}
class B extends A {
}
0
Alexandre N. 8 Ноя 2016 в 18:32