【问题标题】:Stripe Elements with angular 2带角 2 的条纹元素
【发布时间】:2017-10-13 12:49:44
【问题描述】:

我正在尝试将带有 angular 2 的 Stripe 元素与接受信用卡信息的元素卡集成。请注意,我不打算使用条带结帐,因为有几个关于如何将条带与 Angular 2 集成的示例。

declare var Stripe:any;

@Component({
  selector: 'app-account',
  templateUrl: './account.component.html',
  styleUrls: ['./account.component.scss']
})
export class AccountComponent implements OnInit {

  constructor(
    private _zone: NgZone
  ) { }

  private cardToken:any;

  ngOnInit() {

    if (typeof window !== 'undefined') {
      this.setUpCard();
    }
  }


  setUpCard() {
    var stripe = Stripe('TEST_API_KEY');
    var elements = stripe.elements();
    var style = {
      base: {
        fontSize: '16px',
        lineHeight: '24px'
      }
    };

    var card = elements.create('card', {style: style});

    card.mount('#card-element');
  }

  getCardData(number, month, year, cvc) {
      this.getCardToken(number, month, year, cvc);
  }

  getCardToken(number, month, year, cvc) {
    var dataObj = {"number": number, "exp_month": month, "exp_year": year, "cvc": cvc};

    Stripe.card.createToken(dataObj,
      (status, response) => { 

        this._zone.run(() => {
          if (status === 200) {
            this.cardToken = response;
            console.log("the card token: ", this.cardToken);
          }
          else {
            console.log("error in getting card data: ", response.error)
          }
        });
      }
    );
  }

HTML

<form role="form" id="payment-form">
  <div id="card-element">
    <!-- a Stripe Element will be inserted here. -->
  </div>
</form>

当我的组件加载时,我得到这个错误:

您指定的选择器(#card-element)不适用于任何 DOM 元素 当前在页面上的。确保元素存在于 调用 mount() 之前的页面。

如何访问 Angular 2 中的 dom 元素以正常使用 Stripe?

另外,如果这会以某种方式影响 Angular 在客户端上的工作方式,我会在我的 Angular 应用程序上使用服务器端渲染。

【问题讨论】:

    标签: angular stripe-payments


    【解决方案1】:

    希望您已经找到解决问题的方法。但是,由于您的问题没有答案,我会尽力提供帮助。

    您遇到的错误表明问题出在您调用 setUpCard() 的组件生命周期中。 您应该在 AfterViewInit 事件之后调用该方法,即在组件视图初始化时。 所以你需要将你在 ngOnInit() 中使用的代码移动到 ngAfterViewInit() 钩子实现中。

    也看https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#hooks-purpose-timing

    【讨论】:

    • 您好,谢谢。我设法弄清楚它与您建议的 AfterViewInit 有关。这解决了我收到的错误消息的问题,虽然它没有完全解决我的问题,这就是为什么我还没有提出一个可行的解决方案。我相信我的 ssr-setup 遇到了阻碍条带初始化的其他问题。我目前无法访问我的代码来检查我的以下问题是什么,但如果您确定您的解决方案通常可以正常工作,我很乐意接受您的回答!
    • 这并没有解决问题。但乍一看似乎是合乎逻辑的......
    【解决方案2】:

    index.html

    <script src="https://js.stripe.com/v3/"></script>
    

    typings.d.ts

    declare var Stripe: any;
    

    StripeElementsComponent.ts

    export class StripeElementsComponent implements AfterViewInit, OnDestroy { // import AfterViewInit, OnDestroy
        stripe: any;
        elements: any;
        card: any;
        apiKey = 'pk_test______________________'; //replace with your api key
        cardHandler = this.onChange.bind(this);
        error: string;
        @ViewChild('cardInfo') cardInfo: ElementRef; //import viewChild ElementRef
    
        constructor(private cdr: ChangeDetectorRef) {} //import ChangeDetectorRef
    
        ngAfterViewInit() {
            this.stripe = Stripe(this.apiKey);
            this.elements = this.stripe.elements();
            const style = { // input card style optional
                base: {
                    fontSize: '16px',
                    color: '#32325d',
                },
            };
            this.card = this.elements.create('card', {
                style
            });
            this.card.mount(this.cardInfo.nativeElement);
            this.card.addEventListener('change', this.cardHandler);
        }
    
        ngOnDestroy() {
            this.card.removeEventListener('change', this.cardHandler);
            this.card.destroy();
        }
    
        onChange({
            error
        }) {
            if (error) {
                this.error = error.message;
            } else {
                this.error = null;
            }
            this.cdr.detectChanges();
        }
    
        async onSubmitStripe(form: NgForm) { // import NgForm
            const {
                token,
                error
            } = await this.stripe.createToken(this.card);
    
            if (error) {
                console.log('Something is wrong:', error);
            } else {
                console.log('Success!', token); //response 
            }
        }
    }
    

    StripeElementsComponent.html

    <form #checkout="ngForm" (ngSubmit)="onSubmitStripe(checkout)">
        <div class="form-row">
            <label for="card-element">Credit or debit card</label>
            <div id="card-element" #cardInfo></div>
            <div id="card-errors" role="alert" *ngIf="error">{{ error }</div>
        </div>
    <button>Submit Payment</button>
    

    StripeElementsComponent.css

    .StripeElement {
      transition: box-shadow 150ms ease;
      border: solid 3px #e3e3e3;
      border-radius: 0.5em;
      padding: 1.143em 1em;
    }
    
    .StripeElement--focus {
      border-color: #85b7d9;
    }
    
    .StripeElement--invalid {
      border-color: #fa755a;
    }
    
    .StripeElement--webkit-autofill {
      background-color: #fefde5 !important;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2020-03-26
      • 2021-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多