Как передать переменные / переменные-члены от РОДИТЕЛЯ РЕБЕНКУ с помощью ng-content - PullRequest
1 голос
/ 06 августа 2020

У меня есть компонент с такой структурой.

// detail-component.ts

<app-base-modal>
 <app-body></app-body>
</app-base-modal>

На моем базовом модальном компоненте ts. У меня есть это.

//base-modal.component.ts

@Component({
  selector: 'app-base-modal',
  template: `
    <div class="modal fade" bsModal #staticModal="bs-modal" [config]="{backdrop: 'static'}" tabindex="-1" role="dialog" aria-labelledby="dialog-static-name">
            <button type="button" class="close pull-right" aria-label="Close" (click)="staticModal.hide()">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            <ng-content></ng-content>
          </div>
    </div>
  `
})
export class BaseModalComponent implements OnInit {

  @ViewChild('staticModal', { static: true })
  staticModal: ModalDirective;

  @Input()
  toShowModal: BehaviorSubject<boolean> = new BehaviorSubject(false);

  modalIsHidden = false;

  constructor(private modalService: BsModalService) { }

  ngOnInit() {
    this.toShowModal.subscribe(t => {
      if (t) {
        this.staticModal.show();
      }
    });

    this.staticModal.onHidden.subscribe(() => {
      this.modalIsHidden = true;
    })
  }

  closeModal() {
    this.staticModal.hide();
  }

}

Мне нужно передать метод closeModal или modalIsHidden в ng-content, чтобы я мог очистить проецируемый / дочерний элемент html.

модальный компонент тела или дочерний элемент выглядит следующим образом:

//body.component.ts

@Component({
  selector: 'app-body',
  template: `

  <section *ngIf="hasRespondedWithError || isReasonSubmitSuccessful">
    <p class="alert alert-danger" *ngIf="hasRespondedWithError">Something went wrong. Please try again later.</p>
    <p class="alert alert-success" *ngIf="isReasonSubmitSuccessful">Thank you! Please allow us to review your return and we will contact you soon</p>
  </section>

  <form (ngSubmit)="onSubmit()" [formGroup]="sForm">
    <div class="form-group">
      <textarea type="text" formControlName="reasonTextArea" name="reasonTextArea" placeholder="Return Reason" class="form-control"></textarea>
    </div>
    <div class="d-flex flex-row justify-content-end">
      <button type="submit" class="btn btn-primary ml-2">Submit</button>
    </div>
  </form>
`
})
export class BodyComponent {

  @Output()
  returnValueOrder = new EventEmitter<Order>();



  toShowLoading = false;
  hasRespondedWithError = false;
  isReasonSubmitSuccessful = false;

  constructor(private fooService: FooService) { }


  sForm = new FormGroup({
    reasonTextArea: new FormControl('', Validators.required)
  });




  onSubmit(): void {
    this.toShowLoading = true;
    this.fooService
      .createRequest(this.orderNumber, {
        order_id: this.orderId,
        reason: this.sForm.value.reasonTextArea
      })
      .subscribe((order: Order) => {
        this.returnValueOrder.emit(order);
      }, (err) => {
        this.toShowLoading = false;
        this.hasRespondedWithError = true;
      }, () => {
        this.toShowLoading = false;
        this.isReasonSubmitSuccessful = true;
      });
  }

}

Итак, прямо здесь мне нужно проверить / прослушать ли модальный закрыт, поэтому можно установить isReasonSubmitSuccessful и hasRespondedWithError на false.

Я читал это , но это так сбивает с толку. Это сбивает с толку, потому что templateRef должен находиться в том же файле, поэтому я могу ссылаться на него, например, <template #temp></template>, используя знак фунта?

1 Ответ

0 голосов
/ 06 августа 2020

Одним из возможных решений может быть использование механизма внедрения зависимостей :

Сначала определите, что вы хотите передать:

export abstract class ModalContext {
  abstract closeModal();
}

Затем отделите родительский компонент от DI :

base-modal.component.ts

@Component({
  selector: "app-base-modal",
  template: `...`,
  providers: [
    {
      provide: ModalContext,
      useExisting: BaseModalComponent
    }
  ]
})
export class BaseModalComponent implements ModalContext, OnInit {
  ...
  closeModal() {
    ...
  }
}

Наконец, вы можете использовать этот ModalContext в своем спроецированном компоненте:

body.component.ts

@Component({...})
export class BodyComponent {
  ...
  
  constructor(... private modalContext: ModalContext) { }

  closeModal() {
    this.modalContext.closeModal();
  }
}

Forked Stackblitz

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...