Post Ionic (Cordova) 中的新 window / inAppBrowser 中的表单
Post a form in a new window / inAppBrowser in Ionic (Cordova)
我想向外部 url 提交结帐 表单,这应该会打开一个新的 window 并显示结果 ,但我做不到让我的应用打开它,既不在单独的 window 中,也不使用应用内浏览器。
到目前为止,我所做的是创建一个包含表单的指令,然后从链接器函数中,在某个时候调用提交元素。
当我在浏览器中 运行 时,这会打开一个新的 window(如我所愿)。 问题在设备上运行时出现,因为它只是替换 content 我的新内容 WITHOUT OPENING external window.
所以,问题是...当 运行 在设备上时,我如何 post 此表单打开一个新的 window (导航器)或应用内浏览器,并在那里显示结果?
谢谢!!
好吧,解决这个问题很复杂,但最终解决方案 "quite" 很简单。我会 post 在这里帮助任何其他面临同样问题的人。如果有人有更优雅的解决方案,将受到欢迎。
我最后做的是:
- 使用我自己的模板 angular 和我的表单打开新的 window。
- 在新的window控制器中,在全局window对象中创建一个回调函数
- 从旧的 window,在 loadstop 事件之后,执行那个回调
- 新 window 中的 posted 表单重定向到目标页面(这正是我想要的)。
这是代码(请注意,我在表单中使用指令,因此我可以控制何时从 link 函数提交它,并且该数据通过服务与指令共享) :
angular.module('starter', ['ionic'])
.constant('cartData', {
redirectUrl: 'https://test.mycart.com/hpp/pay.shtml',
redirectMethod: 'POST',
redirectData: {
'formParam1': 'value1',
'formPara2': 'value2'
}
}
)
.controller('InitCtrl', function($cordovaInAppBrowser, $scope, cartData) {
$scope.openView = function(){
var counter = 0;
if(ionic.Platform.isWebView()){
$ionicPlatform.ready(function() {
//this is the cordova in app web view
var ref = $cordovaInAppBrowser.open('payment.html', '_blank', {location:'yes'});
$rootScope.$on('$cordovaInAppBrowser:loadstop', function(e, event){
if(counter < 1){
//prevent the callback to be called several times
$cordovaInAppBrowser.executeScript({
code: 'window.paymentCallback('+ angular.toJson(cartData) +');'
});
counter++;
}
});
});
}
};
})
//and then in payment.js
window.paymentCallback = null;
angular.module('payment', [])
.directive('autoSubmitForm', ['$timeout', 'autoSubmitFormDelegate', function($timeout, autoSubmitFormDelegate) {
return {
replace: true,
scope: {},
template: '<form action="{{formData.redirectUrl}}" method="{{formData.redirectMethod}}">'+
'<div ng-repeat="(key,val) in formData.redirectData">'+
'<input type="hidden" name="{{key}}" value="{{val}}" />'+
'</div>'+
'</form>',
link: function($scope, element, $attrs) {
autoSubmitFormDelegate.submitCallback = function(data) {
$scope.formData = data;
$timeout(function() {
element[0].submit();
});
};
}
}
}])
.factory('autoSubmitFormDelegate', function(){
var delegate = {};
delegate.submitCallback = null;
delegate.submitForm = function(data){
if(delegate.submitCallback){
delegate.submitCallback(data);
}
}
return delegate;
})
.controller('PaymentCtrl', function($scope, $timeout, $window, $sce, autoSubmitFormDelegate){
$window.paymentCallback = function(data){
console.log("callback called");
data.redirectUrl = $sce.trustAsResourceUrl(data.redirectUrl);
$timeout(function(){
autoSubmitFormDelegate.submitForm(data);
});
};
})
<link href="http://code.ionicframework.com/1.1.1/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/1.1.1/js/ionic.bundle.min.js"></script>
<body ng-app="starter">
<ion-view view-title="Init">
<ion-content>
<h1>Init</h1>
<button class="button button-positive" ng-click="openView()">Open new view</button>
</ion-content>
</ion-view>
</body>
<script type="text/ng-template" id="payment.html">
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
<title></title>
<script src="../lib/angular/angular.min.js"></script>
<script src="../js/payment.js"></script>
</head>
<body ng-app="payment" ng-controller="PaymentCtrl">
<auto-submit-form></auto-submit-form>
</body>
</html>
</script>
我想向外部 url 提交结帐 表单,这应该会打开一个新的 window 并显示结果 ,但我做不到让我的应用打开它,既不在单独的 window 中,也不使用应用内浏览器。
到目前为止,我所做的是创建一个包含表单的指令,然后从链接器函数中,在某个时候调用提交元素。
当我在浏览器中 运行 时,这会打开一个新的 window(如我所愿)。 问题在设备上运行时出现,因为它只是替换 content 我的新内容 WITHOUT OPENING external window.
所以,问题是...当 运行 在设备上时,我如何 post 此表单打开一个新的 window (导航器)或应用内浏览器,并在那里显示结果?
谢谢!!
好吧,解决这个问题很复杂,但最终解决方案 "quite" 很简单。我会 post 在这里帮助任何其他面临同样问题的人。如果有人有更优雅的解决方案,将受到欢迎。
我最后做的是:
- 使用我自己的模板 angular 和我的表单打开新的 window。
- 在新的window控制器中,在全局window对象中创建一个回调函数
- 从旧的 window,在 loadstop 事件之后,执行那个回调
- 新 window 中的 posted 表单重定向到目标页面(这正是我想要的)。
这是代码(请注意,我在表单中使用指令,因此我可以控制何时从 link 函数提交它,并且该数据通过服务与指令共享) :
angular.module('starter', ['ionic'])
.constant('cartData', {
redirectUrl: 'https://test.mycart.com/hpp/pay.shtml',
redirectMethod: 'POST',
redirectData: {
'formParam1': 'value1',
'formPara2': 'value2'
}
}
)
.controller('InitCtrl', function($cordovaInAppBrowser, $scope, cartData) {
$scope.openView = function(){
var counter = 0;
if(ionic.Platform.isWebView()){
$ionicPlatform.ready(function() {
//this is the cordova in app web view
var ref = $cordovaInAppBrowser.open('payment.html', '_blank', {location:'yes'});
$rootScope.$on('$cordovaInAppBrowser:loadstop', function(e, event){
if(counter < 1){
//prevent the callback to be called several times
$cordovaInAppBrowser.executeScript({
code: 'window.paymentCallback('+ angular.toJson(cartData) +');'
});
counter++;
}
});
});
}
};
})
//and then in payment.js
window.paymentCallback = null;
angular.module('payment', [])
.directive('autoSubmitForm', ['$timeout', 'autoSubmitFormDelegate', function($timeout, autoSubmitFormDelegate) {
return {
replace: true,
scope: {},
template: '<form action="{{formData.redirectUrl}}" method="{{formData.redirectMethod}}">'+
'<div ng-repeat="(key,val) in formData.redirectData">'+
'<input type="hidden" name="{{key}}" value="{{val}}" />'+
'</div>'+
'</form>',
link: function($scope, element, $attrs) {
autoSubmitFormDelegate.submitCallback = function(data) {
$scope.formData = data;
$timeout(function() {
element[0].submit();
});
};
}
}
}])
.factory('autoSubmitFormDelegate', function(){
var delegate = {};
delegate.submitCallback = null;
delegate.submitForm = function(data){
if(delegate.submitCallback){
delegate.submitCallback(data);
}
}
return delegate;
})
.controller('PaymentCtrl', function($scope, $timeout, $window, $sce, autoSubmitFormDelegate){
$window.paymentCallback = function(data){
console.log("callback called");
data.redirectUrl = $sce.trustAsResourceUrl(data.redirectUrl);
$timeout(function(){
autoSubmitFormDelegate.submitForm(data);
});
};
})
<link href="http://code.ionicframework.com/1.1.1/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/1.1.1/js/ionic.bundle.min.js"></script>
<body ng-app="starter">
<ion-view view-title="Init">
<ion-content>
<h1>Init</h1>
<button class="button button-positive" ng-click="openView()">Open new view</button>
</ion-content>
</ion-view>
</body>
<script type="text/ng-template" id="payment.html">
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
<title></title>
<script src="../lib/angular/angular.min.js"></script>
<script src="../js/payment.js"></script>
</head>
<body ng-app="payment" ng-controller="PaymentCtrl">
<auto-submit-form></auto-submit-form>
</body>
</html>
</script>