Подтвердить что ты не робот

AngularJS Paging с $location.path, но без перезагрузки ngView

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

Идеи загружаются с помощью $http:

$scope.flash = new FlashInterface scope:$scope,location:$location

$http.get("/competition.json")
  .success (data) ->
    $scope.flash._init data

Однако, чтобы воспользоваться навигацией по истории и UX, я хочу обновить адресную строку, чтобы отобразить правильный URL-адрес для каждой идеи, используя $location:

$location.path "/i/#{idea.code}"
$scope.$apply()

Я призываю $apply здесь, потому что это событие происходит из-за контекста AngularJS, то есть Flash. Я бы хотел, чтобы текущий контроллер/вид оставался, и чтобы представление не перезагружалось. Это очень плохо, потому что перезагрузка представления приводит к тому, что весь объект флэш-памяти выбрасывается, и цикл предварительного натяжения начинается снова.

Я пробовал прослушивать $routeChangeStart, чтобы сделать preventDefault:

$scope.$on "$routeChangeStart", (ev,next,current) ->
  ev.preventDefault()
$scope.$on "$routeChangeSuccess", (ev,current) ->
  ev.preventDefault()

но безрезультатно. Все это было бы hunky dory, если бы я мог найти способ переопределить перезагрузку вида, когда я изменяю путь $location.path.

Я все еще очень чувствую свой путь вокруг AngularJS, поэтому я был бы рад любым указателям на то, как структурировать приложение для достижения моей цели!

4b9b3361

Ответ 1

Вместо обновления пути просто обновите параметр запроса с номером страницы.

задайте маршрут для игнорирования изменений параметров запроса:

....
$routeProvider.when('/foo', {..., reloadOnSearch: false})
....

и в обновлении вашего приложения $location с помощью:

...
$location.search('page', pageNumber);
...

Ответ 2

От этого сообщения в блоге:

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

Тем не менее, это простой способ закоротить это. angular часы для изменения местоположения (независимо от того, выполнено ли это путем ввода в местоположение, щелчок по ссылке или установка местоположения через $location.path()). Когда он ощущает это изменение, он транслирует event, $locationChangeSuccess и начинает процесс маршрутизации. Какие мы делаем это захват события и reset маршрут к тому, что это было ранее.

function MyCtrl($route, $scope) {
    var lastRoute = $route.current;
    $scope.$on('$locationChangeSuccess', function(event) {
        $route.current = lastRoute;
    });
}

Ответ 3

Моим решением было использовать $routeChangeStart, потому что это дает вам "следующий" и "последний" маршруты, вы можете сравнить их без необходимости дополнительной переменной, например, на $locationChangeSuccess.

Преимущество в том, что вы получаете доступ к свойству "params" как на "следующем", так и на "последнем" пути, например next.params.yourproperty, когда вы используете стиль URL/свойство/значение и, конечно, используете $location.url или $location.path изменить URL вместо $location.search(), который зависит от стиля URL-адреса "? property = value".

В моем случае я использовал его не только для этого, но и для предотвращения изменения маршрута, контроллер не изменился:

$scope.$on('$routeChangeStart',function(e,next,last){
  if(next.$$route.controller === last.$$route.controller){
    e.preventDefault();
    $route.current = last.$$route;
    //do whatever you want in here!
  }
});

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

Ответ 4

Вы должны загружать $location через Injection Dependency Injection и использовать следующее:

$scope.apply(function () {
    $location.path("yourPath");
}

Имейте в виду, что не использовать hashtags (#) при использовании $location.path. Это для совместимости с режимом HTML5.

Ответ 5

Событие $locationChangeSuccess - это немного грубый подход, но я обнаружил, что проверка пути позволяет нам избежать перезагрузки страниц, когда шаблон пути маршрута не изменяется, но перезагружает страницу при переключении на другой шаблон маршрута:

var lastRoute = $route.current;
$scope.$on('$locationChangeSuccess', function (event) {
    if (lastRoute.$$route.originalPath === $route.current.$$route.originalPath) {
        $route.current = lastRoute;
    }
});

Добавление этого кода к определенному контроллеру делает перезагрузку более интеллектуальной.

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

Ответ 6

Мне нужно было это сделать, но, суетившись, пытаясь получить события $locationChange~, чтобы заставить его работать, я узнал, что вы действительно можете сделать это на route, используя resolve.

$routeProvider.when(
    '/page',
    {
        templateUrl : 'partial.html',
        controller : 'PageCtrl',
        resolve : {
            load : ['$q', function($q) {
                var defer = $q.defer();

                if (/*you only changed the idea thingo*/)
                    //dont reload the view
                    defer.reject('');
                //otherwise, load the view
                else
                    defer.resolve();

                return defer.promise;
            }]
        }
    }
);