AngularJS асинхронный анализ href для ссылки

#javascript #angularjs #asynchronous

#javascript #angularjs #асинхронный

Вопрос:

Мне нужно асинхронно обновлять href ссылки. Допустим, у меня есть этот html:

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

И этот угловой контроллер:

 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 . Отредактированный плунжер здесь. К сожалению, это не работает на iPad. На iPad URL страницы не обновляется, потому что на iPad вкладки не могут взаимодействовать друг с другом. Есть идеи?

Комментарии:

1. итак, вы хотите сгенерировать URL-адрес по щелчку?

2. Ваш плунжер работает правильно. Он разрешается через секунду после вашего щелчка. Поэтому, если вы хотите зайти в Google в первый раз, а затем разрешить другой URL, просто измените $scope.url = www.google.com и асинхронная функция к новой. plnkr.co/edit/SSnKwHKpoWCqbhISm2iq?p=preview

3. @KonstantinKrass да. Проблема в том, что мне нужно обработать некоторые вычисления (сгенерировать большой двоичный файл pdf), а затем присвоить URL-адрес большого двоичного объекта ссылке <a>, чтобы пользователь мог загрузить его на новой вкладке.

4. Не уверен, как это сделать с помощью Angular, но могу попробовать: [1] prevent click, [2] disable clicking while process, [3] process link generation, [4] bind link, [5] remove disable, [6] javascript trigger click() event. можно попробовать сделать это кнопкой и оформить как ссылку, чтобы упростить отключение.

Ответ №1:

Если вы хотите вычислить URL-адрес и перенаправить на URL-адрес после щелчка, вы можете просто использовать собственный location.href после получения URL-адреса.

 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;
  }
});
  

И удалите {{url}} из html.

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

Комментарии:

1. На самом деле я не могу использовать window.open(), поскольку он заблокирован в некоторых браузерах (Safari на iPad). И мне (или клиенту ..) Нужно, чтобы он открылся на новой вкладке.

2. Я думаю, что это не может быть достигнуто таким образом, потому что фактическое событие щелчка и перенаправление на URL происходит до того, как любой слушатель сможет ввести новый URL. Чтобы перенаправить впоследствии или зависеть от отложенного URL-адреса, вам нужно предотвратить первое перемещение и использовать location или window Если вы предлагаете загрузку, почему бы не попробовать это с помощью iframe?

Ответ №2:

Это то, что вы хотите: здесь

    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>
  

Комментарии:

1. Мне нужно, чтобы href указывал на google.com даже по первому щелчку мыши. Ваше решение работает, только если я дважды нажму на ссылку.

2. Итак, что должно произойти, если пользователь нажмет на ссылку до того, как ваш файл будет готов?

3. Мне нужно, чтобы браузер подождал, пока он не будет готов, а затем перешел к подготовленному URL. Я просто не могу понять, как дождаться разрешения обещания.