Onsen UI破坏了我的PayPal脚本(以及所有其他javascript)

时间:2016-07-11 17:19:15

标签: javascript node.js express paypal onsen-ui

我一直在慢慢将Onsen UI与我现有的网络应用程序集成。

我的主页文件(index.jade)包含一个分割器,可以在整个应用程序中进行导航。拆分器加载一个NodeJS路由,该路由以jade呈现所请求的页面。到目前为止,一切都按预期工作(实际上我的所有前端玉代码都正确呈现)。分割器的每个页面都存储在一个单独的玉器文件中(主页除外)。

问题:

通过这种方式配置我的应用程序,我通过反复试验了解到我所有jade文件中的所有javascripts都不再使用jade代码呈现(我不知道正确的术语)。如果我将它们剪切并粘贴到index.jade,或者创建单独的javascript文件并将它们包含在index.jade中,我只能让我的javascripts工作。

这本身就是一个问题(虽然我可以通过上面的方法解决它),但这是我主要问题的原因:它在我的一个页面上破坏了我的PayPal脚本。

在整合Onsen UI之前,我在我的应用程序中成功使用了PayPal非文本检查。

代码示例:

这是我在开始集成Onsen UI之前在我的一个视图中实现PayPal的方式:

//- the following is for In-Context PayPal checkout ********************
  div(ng-show="viewEvent && viewEvent.spacesAvailable > 0")
    br
    label(ng-show='eventStatus === 1') This event is being hosted by you! You can not RSVP.  
    label(ng-show='eventStatus === 2') You have RSVP'd for this event, but have not payed.
    label(ng-show='eventStatus === 3') You have already payed for this event.
    label(ng-show='eventStatus === 4') RSVP
    form#myContainer(ng-show='eventStatus === 2 || eventStatus === 4' action="{{'https://10.0.0.25:8001/checkout/' + user._id + '/' + viewEvent._id + '/' + viewEvent.eventName + '/' + viewEvent.price}}" ng-click='rsvp(user._id, viewEvent._id);' method='get')
    script.
      window.paypalCheckoutReady = function () {
        paypal.checkout.setup("**redacted**", {
          environment: "sandbox",
          container: "myContainer"
        });
      };
    script(src='//www.paypalobjects.com/api/checkout.js', async)

我只是将脚本放在那里,所有内容都正确加载,然后我就可以使用PayPal的非文本结账进行购买。 但是,现在我无法像这样插入脚本。我已将代码更改为:

//- the following is for In-Context PayPal checkout ********************
  div(ng-if="viewEvent && viewEvent.spacesAvailable > 0")
    br
    label(ng-show='eventStatus === 1') This event is being hosted by you! You can not RSVP.  
    label(ng-show='eventStatus === 2') You have RSVP'd for this event, but have not payed.
    label(ng-show='eventStatus === 3') You have already payed for this event.
    label(ng-show='eventStatus === 4') RSVP
    form#myContainer(ng-show='eventStatus === 2 || eventStatus === 4' action="{{'https://10.0.0.25:8001/checkout/' + user._id + '/' + viewEvent._id + '/' + viewEvent.eventName + '/' + viewEvent.price}}" ng-click='rsvp(user._id, viewEvent._id);' method='get')
    div(ng-init='openPayPal()')

最后一个div调用角度控制器openPayPal()中的一个函数,该函数调用包含在index.jade中的javascript文件中的函数:

function openPayPal() {
  window.paypalCheckoutReady = function () {
    paypal.checkout.setup("**redacted**", {
      environment: "sandbox",
      container: "myContainer"
    });
  };
}

此外,PayPal脚本:

script(src='//www.paypalobjects.com/api/checkout.js', async)

现在包含在index.jade中。

所以这一切之后,PayPal按钮甚至都没有出现。我相信这是因为我对脚本做错了。

我没有想法。

有谁知道如何实现这一点,或者知道我做错了什么?

此外,有没有人知道如何在jade文件中包含javascript?

谢谢大家的时间。

更新

如果我转到index.jade,删除正文下面的所有内容(包括加载PayPal按钮不起作用的页面的拆分器),并粘贴以下代码,然后PayPal按钮显示为它应该(就像我开始集成Onsen UI之前一样。)

form#myContainer(action='*deleted for now*' method='get')
script.
  window.paypalCheckoutReady = function () {
    paypal.checkout.setup("*redacted*", {
      environment: "sandbox",
      container: "myContainer"
    });
  };
script(src='//www.paypalobjects.com/api/checkout.js' async)

更新2解决方案

我无法从控制器动态加载脚本。这是search.jade中的内容:

  //- the following is for In-Context PayPal checkout ********************
  div(ng-show="viewEvent && viewEvent.spacesAvailable > 0")
    br
    label(ng-show='eventStatus === 1') This event is being hosted by you! You can not RSVP.  
    label(ng-show='eventStatus === 2') You have RSVP'd for this event, but have not payed.
    label(ng-show='eventStatus === 3') You have already payed for this event.
    label(ng-show='eventStatus === 4') RSVP
    form#myContainer(on-load='controller.openPayPalPlease()' ng-show='eventStatus === 2 || eventStatus === 4' action="{{'https://10.0.0.25:8001/checkout/' + user._id + '/' + viewEvent._id + '/' + viewEvent.eventName + '/' + viewEvent.price}}" ng-click='rsvp(user._id, viewEvent._id);' method='get')

这是我在控制器中的角度函数:

this.openPayPalPlease = function() {
    window.paypalCheckoutReady = function () {
      paypal.checkout.setup("H6LX5CJXEQYEL", {
        environment: "sandbox",
        container: "myContainer"
      });
    };

    var s = document.createElement('script');
    s.setAttribute('src', '//www.paypalobjects.com/api/checkout.js');
    document.getElementById('myContainer').appendChild(s);
  };

注意我如何在jade文件中的PayPal表单中使用 on-load 调用angular函数。不使用 on-load ,并将此div放在PayPal表单下,

div(ng-init='controller.openPayPalPlease()')

我收到错误:

  

无法阅读属性" appendChild'在openPayPalPlease

的null

使用on-load,没有任何反应,并且脚本不会被加载。

2 个答案:

答案 0 :(得分:1)

我猜想,由于某些情况,您要么没有正确调用您的功能,要么在它准备好之前尝试调用它。

Sidenote :虽然这可能不是问题 - 现在你正在调用一个全局函数 - 在角度上有2种常见的事件处理方式。

方式1 (陈旧但常见的方式)

module.controller('MyController', function($scope) {
    $scope.myHandler = function() { ... };
});

<div ng-controller="MyController">
    <div ng-event-name="myHandler()"></div>
</div>

方式2 (新的,推荐的)

module.controller('MyController', function() {
    this.myHandler = function() { ... };
});

<div ng-controller="MyController as MC">
    <div ng-event-name="MC.myHandler()"></div>
</div>

所以你可以尝试使用其中一种方法。此外,您可以尝试在console.logopenPayPal函数中执行一些paypalCheckoutReady,以确保一切正常。您还应该检查控制台中是否出现任何错误。 (右键单击→检查元素→控制台)

<强>更新

我检查了paypalobjects.com/api/checkout.js的实现,我想我发现了正在发生的事情。

在此之前我一直在期待你仍然在调用你的paypalCheckoutReady函数,但似乎实际上checkout脚本会检查它是否存在并执行它,否则它会执行一个默认函数。由于您是定义该函数的人,因此您实际上应该能够在其中添加console.log并看到它未被执行。

因为您说过将paypal脚本移动到index.jade,这意味着它在您的实际代码执行之前很久就被执行了。值得庆幸的是,如果您没有具有属性data-paypal-(button|id|sandbox)的元素,则调用的默认函数不会执行任何操作,因此您是安全的。

唯一剩下的就是打电话给你的功能。我检查了脚本的实现,所以它对你的函数做的唯一事情是在页面加载后调用它。所以在你的情况下你可以自己调用它。您可以在定义paypalCheckoutReady函数后添加此行,如下所示:

window.paypal && window.paypalCheckoutReady();

或者,您可以从控制器动态加载paypal脚本。从概念层面来看,这可能是一个优雅的解决方案,因为它可以为您提供对程序流程的更多控制。 像

这样的东西
var s = document.createElement('script');
s.setAttribute('src', '//www.paypalobjects.com/api/checkout.js');
parent.appendChild(s);

其中parentdocument.bodydocument.head,您的网页或您喜欢的任何内容。您还可以进行一些检查以防止第二次加载脚本。

我认为两种解决方案都应该有效,所以你可以使用你喜欢的解决方案。

答案 1 :(得分:0)

PayPal有一个问题,如果document.readyState == 'interactive'那么你的函数就不会被调用。您只需在调试控制台中键入document.readyState即可验证这一点。

如果你的资源仍在加载,可能就是这种情况 - 但是我也相信当前版本的Chrome中存在一个错误,我正在尝试重现这些错误以便报告。

检查&#39;网络&#39; Chrome调试工具的标签,用于查找任何长时间运行的请求。

我也向PayPal报告了此问题,但他们通常没有希望,所以我不希望他们修复它。

我最终设置了5秒的超时,然后检查window.paypal是否已初始化,如果是,我只是自己调用我的初始化函数并设置一个布尔值以防止它再次发生。