Выдать событие из динамически созданного дочернего компонента в родительский компонент - PullRequest
4 голосов
/ 20 марта 2019

У меня есть слайдер, в котором динамически создаются элементы - это дочерние компоненты.

Родительский шаблон, где находится ng-контейнер для слайдера:

<div id="slider-wrapper">
    <ng-container appSliderForm *ngFor="let question of questionsInSlider"
                          [questionTest]="question" (onRemove)="removeQuestion($event)">
    </ng-container>
</div>

Эти дочерние компоненты создаютсяДиректива appSliderForm:

@Directive({
  selector: '[appSliderForm]'
})
export class FormSliderDirective implements OnInit {

  @Input()
  questionTest: QuestionInSlider;

  constructor(private resolver: ComponentFactoryResolver, private container: ViewContainerRef) {}

  ngOnInit(): void {
    const factory = this.resolver.resolveComponentFactory<TestQuestionInSliderComponent>(TestQuestionInSliderComponent);
    const component = this.container.createComponent(factory);
    component.instance.questionTest = this.questionTest;
    component.instance.ref = component;
  }

}

В моем дочернем компоненте есть функция удалить для удаления себя из ползунка.

@Component({
  selector: 'app-test-question-in-slider',
  templateUrl: './test-question-in-slider.component.html',
  styleUrls: ['./test-question-in-slider.component.less']
})
export class TestQuestionInSliderComponent {

  questionTest: QuestionInSlider;

  ref: any;

  @Output() public onRemove = new EventEmitter<QuestionInSlider>();

  constructor(private builderService: FormBuilderService) {}

  /**
   * Chosen question from slider will be displayed.
   */
  choose(): void {
    this.questionTest.chosen = true;
    this.builderService.handlerQuestionFromSlider(this.questionTest);
  }

  remove(): void {
    this.onRemove.emit(this.questionTest);
    this.ref.destroy();
  }

  isChosen() {
    return {'chosen': this.questionTest.chosen};
  }

  getBorderTopStyle() {
     return {'border-top': `4px solid ${this.questionTest.color}`};
  }

}

Когда вызывается эта функция удалениящелкнув значок удаления в шаблоне дочернего компонента, я хотел бы отправить событие, чтобы сообщить родительскому компоненту о выполнении других операций в соответствии с ним, но функция removeQuestion в родительском компоненте не вызывается.

Не могли бы вы сообщить мне, пожалуйста, почему не вызывается эта функция removeQuestion?

removeQuestion(question: QuestionInSlider) {
    console.log(question);
  }

ОБНОВЛЕНИЕ

Я отладил ее в браузере Chrome, и яувидел, что у моего объекта onRemove EventEmitter не было никаких значений в его свойстве массива наблюдателей, когда была вызвана функция emit для onRemove object.

this.onRemove.emit(this.questionTest);

Debug

1 Ответ

2 голосов
/ 20 марта 2019

Проблема в том, что FormSliderDirective не имеет события onRemove. Чтобы ваш код работал, вам нужно добавить событие в директиву и подписать его на событие внутреннего компонента. Таким образом, всякий раз, когда происходит внутреннее событие, оно будет распространяться наружу.

Вот пример того, как вы можете добавить это в вашу директиву:

@Directive({
  selector: '[appSliderForm]'
})
export class FormSliderDirective implements OnInit {

  @Input() questionTest: QuestionInSlider;
  @Output() public onRemove = new EventEmitter<QuestionInSlider>();

  constructor(private resolver: ComponentFactoryResolver, private container: ViewContainerRef) {}

  ngOnInit(): void {
    const factory = this.resolver.resolveComponentFactory<TestQuestionInSliderComponent>(TestQuestionInSliderComponent);
    const component = this.container.createComponent(factory);
    component.instance.questionTest = this.questionTest;
    component.instance.onRemove.subscribe(this.onRemove); // this connects the component event to the directive event
    component.instance.ref = component;
  }

}
...