当我在recaptcha框中打勾时,ui-router似乎崩溃了。页面上具有ui-sref属性的所有链接都停止工作,但我没有收到任何错误消息。请查看我已设置的this plunker。你知道原因可能是什么吗?
的script.js
var app = angular.module('app', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'home.html',
controller: function() {
grecaptcha.render('captcha', {
sitekey: "--sitekey--"
})
}
})
.state('other', {
templateUrl: 'other.html'
});
$urlRouterProvider.otherwise('/');
})
的index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js@*" data-semver="1.4.0-rc.0" src="https://code.angularjs.org/1.4.0-rc.0/angular.js"></script>
<script data-require="ui-router@*" data-semver="0.2.13" src="//rawgit.com/angular-ui/ui-router/0.2.13/release/angular-ui-router.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<ui-view></ui-view>
</body>
home.html的
<h1>Home</h1>
<p>Click the re-captcha, then try to change state by clicking the link below.</p>
<p><a ui-sref="other">Go to other state</a></p>
<div id="captcha"></div>
other.html无关紧要。
更新 我注意到状态转换仅在目标状态定义了url时失败,并且我设法将其缩小到ui-router源代码中的下一段代码(ui-sref指令) :
element.bind("click", function(e) {
var button = e.which || e.button;
if ( !(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || element.attr('target')) ) {
// HACK: This is to allow ng-clicks to be processed before the transition is initiated:
var transition = $timeout(function() {
$state.go(ref.state, params, options);
});
e.preventDefault();
// if the state has no URL, ignore one preventDefault from the <a> directive.
var ignorePreventDefaultCount = isAnchor && !newHref ? 1: 0;
e.preventDefault = function() {
if (ignorePreventDefaultCount-- <= 0)
$timeout.cancel(transition);
};
}
});
正如您所看到的,正在重写e.preventDefault函数以取消将触发状态更改的超时。如果你在上面的活页夹中注释掉这段代码,状态转换就会起作用:
//e.preventDefault = function() {
// if (ignorePreventDefaultCount-- <= 0)
// $timeout.cancel(transition);
//};
通常ui-router在每个锚链接上每次点击都会调用e.preventDefault()一次,但是当勾选reCaptcha时,它似乎被调用了两次。我猜这可能与问题有关,但我并非100%肯定。也许拥有更好调试技能的人可以理解正在发生的事情。 Here's a plunker证明了这种行为。
答案 0 :(得分:4)
我找到了一种简单的方法来解决角度上任何类型的路由器的问题。当grecaptha未定义时,这意味着我们遇到了同步问题。因此,在我/您的控制器中,您应该使用例如&lt;&lt;来加载脚本。 $ .getScript(“URL”)&gt;&gt;
SO:
在HTML中
<div class="g-recaptcha" data-sitekey="YourSiteKey"></div>
在你的控制器中:
$.getScript("https://www.google.com/recaptcha/api.js");
在这里,你的grecaplecha就像你第一次加载页面一样。
答案 1 :(得分:1)
使用角度路由时出现相同的错误。
您可以通过下列代码解决此问题:
你的script.js中的
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"></script>
:
var app = angular.module('app', ['ui.router']); app.config(function($stateProvider, $urlRouterProvider) { $stateProvider.state('home', { url: '/', templateUrl: 'home.html', controller: function() { function onloadCallback() { grecaptcha.render('yourHTMLElementId', { 'sitekey' : 'yourSiteKey' }); } onloadCallback(); } }) .state('other', { templateUrl: 'other.html' }); $urlRouterProvider.otherwise('/'); })