Передать URL как $routeParam в приложении AngularJS - программирование
Подтвердить что ты не робот

Передать URL как $routeParam в приложении AngularJS

Как передать фактический URL (с косой чертой, запятыми и т.д.) в качестве $routeParam в приложение AngularJS?

это будет работать: http://paprikka.github.io/le-bat/#/preview/asdadasda

это не будет: http://paprikka.github.io/le-bat/#/preview/http://page.com

и это не будет: http://paprikka.github.io/le-bat/#/preview/http%3A%2F%2Fpage.com

или это: http://paprikka.github.io/le-bat/#/preview/?url=http%3A%2F%2Fpage.com

Подробнее

Механизм маршрутизации AngularJS по своей конструкции не позволяет передавать строки с косой чертой в качестве параметров запроса. Я могу понять причины этого решения - мы не хотим создавать здесь безгосударственный сервер.

Однако все еще существуют случаи, когда использование разных разделителей или регулярных выражений в маршрутах может быть необходимо.

Я хотел создать приложение, которое принимает параметр строки хэш-строки url и загружает его содержимое в iframe (

4b9b3361

Ответ 1

Хорошо, мне удалось найти решение, работающее с текущей стабильной версией (@1.0.7).

В текущем способе решения этой проблемы будут связаны события, связанные с трафиком, разбора angular -независимых URL-адресов на лету и обработки их с помощью дополнительной службы, работающей аналогично перехвату $http.

Здесь вы можете увидеть примеры рабочих кодов: http://embed.plnkr.co/fIA2xj/preview

Основные шаги

  • передайте angular -независимый URL-адрес, как обычно, например. перейдите на сайт site.com/url/http://site.com
  • прослушать событие $routeChangeStart и извлечь правильный URL-адрес для путей, начинающихся с /url/
  • закодировать правильный параметр url в angular -патентной форме (в данном конкретном случае я использую base64). Не используйте encodeURIComponent, потому что angular будет обрабатывать как любой другой URL
  • перенаправлять на другой маршрут с помощью бизнес-логики, например. site.com/parsed-url/BASE64_GOES_HERE
  • декодировать URL-адрес в контроллере и использовать его как обычно:)

код

Создайте модуль приложения angular как обычно

angular.module('routes',[]).config([

  '$routeProvider',

  function($routeProvider){
    $routeProvider
      .when('/test', {templateUrl: 'test.html'})
      // This one is important:
      // We define a route that will be used internally and handle 
      // parameters with urls parsed by us via the URLInterceptor service 
      .when('/parsed-url/:url', {templateUrl: 'url.html', controller:'URLCtrl'})
      .when('/', {redirectTo: '/test'})
      .otherwise({templateUrl: '404.html'});

  }

])

Служба перехвата URL (singleton)

.service('URLInterceptor', function($rootScope, $location){
  // We listen to $routeChangeStart event and intercept it if 
  // the path matches our url scheme. In this case, every route
  // beginning with /url/ will be caught
  $rootScope.$on('$routeChangeStart', function(e, next, current){

    // $location.path does change BEFORE actual routing happens,
    // so in this case we get parsed new location object
    // for free.

    // To be hones, a better way of handling this case might be using 
    // $locationChangeStart event instead, but it would require us to parse urls 
    // manually.
    var path = $location.path();
    // check if string begins with '/url/'
    var matcher = path.slice(0,5);
    var cleanPath = '';
    if (matcher === '/url/'){
      // Yes it does, yay!
      // Remove leading '/url/' to extract the actual parameter
      cleanPath = path.slice(5);
      // Encode our url to a safe version. We know that encodeURIComponent won't 
      // work either, so a good choice might be base64.
      // I'm using https://code.google.com/p/javascriptbase64/downloads
      $location.path('/parsed-url/' + Base64.encode(cleanPath));
      // Prevent default event execution. Note that, it won't cancel related $location Events
      e.preventDefault();
    }
  });

  return {
    decode: Base64.decode,
    encode: Base64.encode
  }
})

Контроллеры

// Main application controller
// We instantiate our URLInterceptor service here
.controller('AppCtrl',function($scope, $location, URLInterceptor){
  $scope.navigateTo = function (path) {
    $location.path('/url/' + path);
  }
})
.controller('URLCtrl', function($scope, $routeParams, URLInterceptor){
  $scope.url = URLInterceptor.decode($routeParams.url);
});

Две вещи, которые вы должны запомнить:

  • Хотя я пытался создать решение как можно более чистым, обычно передача данных таким образом, чтобы angular не считается хорошей практикой, поэтому постарайтесь не использовать его, если вам действительно не нужно.
  • Вы можете справиться с этой проблемой только одним маршрутом. Я просто считаю это более чистым.

Ответ 2

Используя $routeProvider в Angular 1.2, вы можете передать URL-адрес, если он находится в конце пути, добавив asterik к шаблону. Следующее должно работать независимо от того, вы URLComponentEncode URL.

Маршрут:

angular.module('angularApp', ['ngRoute'])
      .when('/frame/:picture_url*', {
        templateUrl: 'views/frame.html',
        controller: 'PictureFrame'
      });

Контроллер:

      .controller('PictureFrame', function($scope, $routeParams, $sce){
        //whitelist the URL
        $scope.picture_url = $sce.trustAsResourceUrl($routeParams.picture_url);
      });

Затем в вашем шаблоне:

<iframe ng-src="{{picture_url}}"></iframe>

Ответ 3

У меня есть решение, но я не знаю, поможет ли это вам. Из Angular documention http://docs.angularjs.org/api/ng. $Location $location имеет функцию поиска (поиск, paramValue)

Чтобы передать параметр:

parameter = encodeURIComponent url
$location.search({ yourURLParameter: parameter }).path('/preview')

Чтобы прочитать параметр:

url = decodeURIComponent $location.search().yourURLParameter

Конечно, вам нужно ввести $location зависимость

Ответ 4

У меня есть смешанные параметры поиска с маршрутами. Ваш поиск должен появиться перед вашими маршрутами.. специально для старых браузеров. Я думаю, что ie7 взрывается, если его не url/?search/#/hash

Попробуйте этот формат:

domain.com/?my=params&another=param/#/my/hashes