AngularJS异步分配href到链接

4

我需要异步更新链接的 href。假设我有以下 HTML:

<a ng-href="{{url}}" ng-click="resolveUrl()" target="_blank">click me</a>

还有这个Angular控制器:

app.controller('MainCtrl', function($scope, $q) {
  $scope.url = '#';

  $scope.resolveUrl = function() {
    async().then(function(resolvedUrl){
      $scope.url = resolvedUrl;
    });
  }

  function async() {
    var deffered = $q.defer();

    setTimeout(function() {
      deffered.resolve('http://www.google.com');
    }, 1000)

    return deffered.promise;
  }
});

即使是第一次,我也需要链接跳转到google.com。如何同步异步调用或如何分配URL以便异步函数解决?

在plunker中的代码

编辑:

正如@Konstantin Krass所指出的那样,我可以使用window.open()。但是,我无法异步使用它,因为浏览器将阻止弹出新窗口。因此,我尝试在单击后打开另一个窗口(不被阻止),然后在承诺解决后更新打开窗口的URL到google.com。编辑plunker在这里。不幸的是,这在iPad上不起作用。在iPad上,页面URL未更新,因为在iPad上,选项卡无法相互通信。有什么想法吗?


你想在点击时生成URL吗? - Konstantin Krass
你的 Plunker 正常工作。它在你点击后一秒钟解析。所以,如果你想第一次去谷歌,然后解析另一个 URL,只需更改 $scope.url = www.google.com 和异步函数到新的 URL。http://plnkr.co/edit/SSnKwHKpoWCqbhISm2iq?p=preview - Mario Levrero
@KonstantinKrass 是的。问题在于我需要处理一些计算(生成Blob PDF),然后将Blob URL分配给<a>链接,以便用户可以在新标签页中下载它。 - daerin
不确定如何在Angular中实现,但可以尝试:[1] 防止点击,[2] 在处理过程中禁用点击,[3] 处理链接生成,[4] 绑定链接,[5] 移除禁用,[6] JavaScript触发click()事件。可以将其制作为按钮并将其样式设置为链接,以使禁用更简单。 - user887675
2个回答

1
如果你想计算URL并在单击后重定向到该URL,则只需在接收到URL后使用本地的location.href即可。
app.controller('MainCtrl', function($scope, $q) {     

  $scope.resolveUrl = function() {
    async().then(function(resolvedUrl){
      location.href= resolvedUrl; //this would open the url in the current page.
      // if you want to offer a download or move 
      // into new browser tab you can go like this: 
      // window.open(resolvedUrl);  
    });
  }

  function async() {
    var deffered = $q.defer();

    setTimeout(function() {
      deffered.resolve('http://www.google.com');
    }, 1000)

    return deffered.promise;
  }
});

从HTML中删除{{url}}

<a ng-click="resolveUrl()">click me</a>

实际上我不能使用window.open(),因为在某些浏览器(如iPad上的Safari)中被阻止了。而且我(或客户...)需要它在新标签页中打开。 - daerin
我认为这样做是不可行的,因为实际的点击事件和重定向到URL发生在任何监听器注入新URL之前。要在之后重定向或依赖延迟的URL,您需要阻止第一次重定向并使用location或window。如果您提供下载,为什么不尝试使用iframe? - Konstantin Krass

0

你想要的是这个吗:这里

   app.controller('MainCtrl', function($scope, $q) {
  $scope.message = 'Create File';

  $scope.resolveUrl = function() {
    async().then(function(resolvedUrl){
       $scope.message  = "Download File"
      $scope.url = resolvedUrl;
    });
  }

  function async() {
    var deffered = $q.defer();

    setTimeout(function() {
      deffered.resolve('http://www.google.com');
    }, 1000)

    return deffered.promise;
  }
});
HTML:

  <body ng-controller="MainCtrl">
    <a ng-href="{{url}}"  ng-click="resolveUrl()" target="_blank">{{message}}</a>
  </body>

我需要href在第一次点击时就指向google.com。你的解决方案只有在我点击链接两次时才有效。 - daerin
如果用户在您的文件准备好之前点击链接,那么应该发生什么? - sylwester
我需要浏览器等待直到准备就绪,然后转到准备好的URL。我只是无法弄清楚如何等待承诺解决。 - daerin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接