Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/470.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 应用程序组件看不到index.html中声明的条带元素?_Javascript_Angular_Typescript_Stripe Payments - Fatal编程技术网

Javascript 应用程序组件看不到index.html中声明的条带元素?

Javascript 应用程序组件看不到index.html中声明的条带元素?,javascript,angular,typescript,stripe-payments,Javascript,Angular,Typescript,Stripe Payments,我正在尝试创建一个Stripe elements集成的stackblitz演示 我有如下声明的条带元素: <!DOCTYPE html> <html lang="en"> <body> <script src="https://js.stripe.com/v3/"></script> <script type="text/javascript"> var stripe = Stripe('pk_test_2s

我正在尝试创建一个Stripe elements集成的stackblitz演示

我有如下声明的条带元素:

<!DOCTYPE html>
<html lang="en">
<body>
  <script src="https://js.stripe.com/v3/"></script>
  <script type="text/javascript">
    var stripe = Stripe('pk_test_2syov9fTMRwOxYG97ABSFGSDAXbOgt008X6NL46o');t
    var elements = stripe.elements();
  </script>
  <my-app></my-app>
</body>
</html>


变量条带=条带('pk_测试2syov9fTMRwOxYG97ABSFGSDAXbOgt008X6NL46o');T
var elements=stripe.elements();
但是,
app.component.ts
文件似乎没有拾取
elements
,也没有将其视为全局元素


你知道如何解决这个问题吗?

使用类型脚本,你应该使用npm包在组件内部使用它。

在本例中,您所采用的方法只是将其添加到全局窗口DOM元素中,这与Angular框架的工作方式大相径庭。从技术上讲,您可以使用这些变量window.stripe和window.elements来访问它,但我不推荐这样做。最好遵循Stripe文档提供的指南


问题在于Angular可以在加载条带API的同时加载组件。这将导致竞争条件

如果通过脚本标记加载条带API,则组件可以使用它。如果不是,则组件将不会正确呈现,因为调用
stripe.elements()
时出错

要解决这个问题,我们必须先听脚本完成,然后使用StripeAPI

这是一个可以做到这一点的服务。您注入服务,然后调用:


  setPublishableKey(key:string, options?:any):Promise<Stripe>{
    return this.stripePromise.then( () => {
      return this.stripe(key, options)
    })
  }


setPublishableKey(键:字符串,选项?:任意):承诺{
返回这个.stripePromise.then(()=>{
返回此.stripe(键、选项)
})
}
这就是整个服务:

import { Injectable } from '@angular/core';
import { Stripe, StripeFactory } from './types';

const STRIPE_API_URL = "https://js.stripe.com/v3/";

@Injectable({
  providedIn: 'root'
})
/**
 * This service has a `stripe` property to that gets
 * initialized to `window["Stripe"]`.
 * 
 * The constructor calls `inject()` which will
 * inject a script tag with containing the URL that loads
 * stripe and return a `Promise<StripeFactory>`.
 * 
 * The script tag will only load stripe if 
 * c is not available.
 * 
 * If `window["Stripe"]` is available then `inject()` resolves 
 * the promise with that instance immediately, and does not create and 
 * wait for the script tag to load.
 * 
 *  
 */
export class AngularStripeService{

  private _stripe:StripeFactory = window["Stripe"]
  private stripePromise:Promise<any>

  constructor() { 
    this.stripePromise = this.inject()
  }

  get stripe() {
    return this._stripe;
  } 
  set stripe(s:StripeFactory) {
    this._stripe = s;
  }

  setPublishableKey(key:string, options?:any):Promise<Stripe>{
    return this.stripePromise.then( () => {
      return this.stripe(key, options)
    })
  }

  inject():Promise<StripeFactory>{

    if( this.stripe ){
      return Promise.resolve( this.stripe )
    }

    return new Promise((res,rej)=>{
      const head = this.getHeadElement()
      const script = document.createElement("script")
      script.setAttribute("type", "text/javascript")
      script.setAttribute("src", STRIPE_API_URL)      
      head.appendChild(script)      
      script.addEventListener("load",()=>{
        this.stripe = window["Stripe"];
        res( this.stripe )
      })
    })
  }

  /**
   * Returns the `head` element.
   * @throws Error('Application does not have a head element');
   */
  getHeadElement(){
    let elm:HTMLElement = document.getElementsByTagName("head")[0]

    if(!elm) {
      throw new Error('Application does not have a head element');
    }    
    return elm
  }  
}
从'@angular/core'导入{Injectable};
从“./types”导入{Stripe,StripeFactory};
常量条带\u API\u URL=”https://js.stripe.com/v3/";
@注射的({
providedIn:'根'
})
/**
*此服务的“stripe”属性
*已初始化为“窗口[“条带”]”。
* 
*构造函数调用'inject()',这将
*插入包含加载的URL的脚本标记
*条纹并返回“承诺”。
* 
*脚本标记仅在以下情况下加载条带:
*c不可用。
* 
*如果'window[“Stripe”]`可用,则'inject()`解析
*承诺立即与该实例关联,并且不会创建和
*等待脚本标记加载。
* 
*  
*/
导出类AngularStripeService{
private _stripe:StripeFactory=window[“stripe”]
私人脱衣舞表演:承诺

以及该服务的演示:

import { Injectable } from '@angular/core';
import { Stripe, StripeFactory } from './types';

const STRIPE_API_URL = "https://js.stripe.com/v3/";

@Injectable({
  providedIn: 'root'
})
/**
 * This service has a `stripe` property to that gets
 * initialized to `window["Stripe"]`.
 * 
 * The constructor calls `inject()` which will
 * inject a script tag with containing the URL that loads
 * stripe and return a `Promise<StripeFactory>`.
 * 
 * The script tag will only load stripe if 
 * c is not available.
 * 
 * If `window["Stripe"]` is available then `inject()` resolves 
 * the promise with that instance immediately, and does not create and 
 * wait for the script tag to load.
 * 
 *  
 */
export class AngularStripeService{

  private _stripe:StripeFactory = window["Stripe"]
  private stripePromise:Promise<any>

  constructor() { 
    this.stripePromise = this.inject()
  }

  get stripe() {
    return this._stripe;
  } 
  set stripe(s:StripeFactory) {
    this._stripe = s;
  }

  setPublishableKey(key:string, options?:any):Promise<Stripe>{
    return this.stripePromise.then( () => {
      return this.stripe(key, options)
    })
  }

  inject():Promise<StripeFactory>{

    if( this.stripe ){
      return Promise.resolve( this.stripe )
    }

    return new Promise((res,rej)=>{
      const head = this.getHeadElement()
      const script = document.createElement("script")
      script.setAttribute("type", "text/javascript")
      script.setAttribute("src", STRIPE_API_URL)      
      head.appendChild(script)      
      script.addEventListener("load",()=>{
        this.stripe = window["Stripe"];
        res( this.stripe )
      })
    })
  }

  /**
   * Returns the `head` element.
   * @throws Error('Application does not have a head element');
   */
  getHeadElement(){
    let elm:HTMLElement = document.getElementsByTagName("head")[0]

    if(!elm) {
      throw new Error('Application does not have a head element');
    }    
    return elm
  }  
}

Hi-我尝试了这种方法,但现在我得到了一个错误,即无法找到
http
https
包。这是更新的stackblitz:我认为这对您不起作用,因为该库是用于节点的。幸运的是,有人已经创建了一个教程,介绍如何按照您以前尝试的方式进行操作,而不导入that库。-创建类型,然后在组件中使用。我在演示中有这个设置-但这也不起作用…这实际上是我遵循的教程:)