В настоящее время я интегрирую Stripe в Angular. Реализация работает нормально, пока я не начал перемещать элементы полосы в ngSwitchCase и ng-container

Вот тогда я и начал получать эту ошибку:

ERROR IntegrationError: The selector you specified (#card-element) applies to no DOM elements 
that are currently on the page.
Make sure the element exists on the page before calling mount()

Причина в том, что полоса пытается mount элемент до того, как появится ngSwitchCase. Я пробовал использовать ngAfterViewInit, но кажется, что функция выполняется один раз, когда компонент визуализируется в первый раз, а не когда ngSwitch меняет представление.

Есть ли способ обнаружить изменения в представлении компонента? Таким образом, я знаю, когда mount() элементы Stripe после того, как компонент полностью отрисован. Обратите внимание, что ниже я использую ng-container, который не добавляет узлы DOM в HTML, согласно документации Angular.

<ng-container [ngSwitch]="selectedForm">
        <ng-container *ngSwitchCase="'FORM_ONE'">
          <form>
              ...
          </form>
        </ng-container>
        <ng-container *ngSwitchCase="'FORM_TWO'">
          <form>
              ...
          </form>
        </ng-container>
        <ng-container *ngSwitchCase="'FORM_THREE'">
           // Stripe 'card-element'
          <form action="/charge" method="post" id="payment-form">
              <label for="card-element">Credit or debit card</label>
              <div id="card-element"></div>
              <div id="card-errors" role="alert"></div>
          </form>
  </ng-container>
</ng-container>
1
chris 24 Сен 2020 в 20:44

1 ответ

Лучший ответ

В шаблоне добавьте имя к карточке

<ng-container *ngSwitchCase="'FORM_THREE'">
           // Stripe 'card-element'
          <form action="/charge" method="post" id="payment-form">
              <label for="card-element">Credit or debit card</label>
              <div #stripeCard id="card-element"></div>
              <div id="card-errors" role="alert"></div>
          </form>
  </ng-container>

Теперь вы можете получать уведомления при рендеринге с помощью сеттера. в компоненте:

 card:ElementRef;
 @ViewChild('stripeCard') set content(content: ElementRef) {
    if(content) { // initially setter gets called with undefined
         
        //mount it here...
     
       //for future reference...  
       this.card=content;
    }
 }
2
emmbee 24 Сен 2020 в 18:19