Запретить перезагрузку представления на основе ui-router при изменении параметра запроса

Обновленный вопрос

Вопрос в заголовке еще стоит - можно ли поймать ?parameters и отменить просмотр перезагрузки.

Оригинальный вопрос: Мне нужно добавить поддержку привязки для моего приложения (привязки к темам).

Здесь, насколько я:

angular.module('app.topics', [
    'ui.state',
    'ui.router',
    'restangular'
    'app.topics.controllers'
])
.config(function config($stateProvider) {
    $stateProvider.state('viewtopic', {
        url: '/topics/:slug?section',
        onEnter: function($stateParams) {
            // Works, as state has been reloaded.
            console.log('$stateParams', $stateParams);
        },
        resolve: {
            topic: function ($stateParams, Topic) {
                // Wrapper around Restangular. Returns promise.
                return new Topic().get($stateParams.slug);
            }
        },
        views: {
            'main': {
                controller: 'TopicCtrl',
                templateUrl: 'topics/templates/details.tpl.html'
            },
            'sidebar': {
                controller: 'SidebarCtrl',
                templateUrl: 'topics/templates/sidebar.tpl.html'
            }
        }
    });
});

angular.module('app.topics.controllers', [])
    .controller('TopicCtrl', function ($scope, topic, $rootScope, $location,
                                         $anchorScroll, $stateParams) {
        $scope.topic = topic;
        $scope.slug = $stateParams.slug;
        $scope.section = $stateParams.section;
        // ..

        $scope.$watch('$stateParams.section', function (newValue, newValue) {
            // Does not work.
            console.log('stateParams.section changed', newValue, newValue);
        });
    });

Моя корневая проблема - когда я нажимаю ссылку на #/topics/slug-name?section=section-1, состояние перезагружается полностью, что в свою очередь повторно запрашивает данные для темы. Как можно просто "обновить" параметры запроса (и поймать это событие в контроллере), но не перезагрузить состояние (чтобы сохранить данные)?

ИЗМЕНИТЬ

Для моей проблемы существует довольно простое решение, которое я не заметил - per Документация AngularJS в "Режимах Hashbang и HTML5" - последний хэш доступен через $location.hash(), а прокрутка может быть инициирована $anchorScroll()

Итак, мое текущее решение:

В контроллере:

$scope.$watch('$location.hash', function () {
    _.defer($anchorScroll);
});

Отсрочка необходима, потому что контент еще не анализируется, и нет идентификаторов.

В шаблоне мне просто нужно было установить цель на #/topics/slug-name#section-name.

Ответ 1

Вы пробовали параметр reloadOnSearch в определении маршрутов?

{
    route:'/',
    resolve: {
        templateUrl:'template.html',
        reloadOnSearch: false
    }
},

Ответ 2

Мои два цента

Сначала проверьте @doodeec ответ о настройке reloadOnSearch на false:

{
    route:'/',
    resolve: {
        templateUrl:'template.html',
        reloadOnSearch: false
    }
},

Затем на контроллере вы хотите поймать это:

/* Setup to detect when there is a change in the search */
$scope.$on('$routeUpdate', function(next, current) {
   // Do something when routeupdate is called. 
});

В случае, если вы хотите изменить поиск:

$location.search({'slide_id': slide_id})

Также позаботьтесь о маленьком Gotcha:

Если параметры маршрута не изменяются (или меняются на одно и то же значение), поскольку перезагрузка отключена, вам может потребоваться принудительное изменение местоположения:

$scope.$emit('$locationChangeSuccess');

Из комментариев:

Без ngRoute не будет события $routeUpdate. в этом случае вам нужно слушать $scope.$on('$locationChangeSuccess', ...) вместо

Ответ 3

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

 $stateProvider.state('viewtopic', {abstract:true,
url:/topics,
resolve: {
            topic: function ($stateParams, Topic) {
                // Wrapper around Restangular. Returns promise.
                return new Topic().get($stateParams.slug);
            }
        },
views: {
templateUrl:<template>
}
});

$stateProvider.state('viewtopic.impl', {abstract:true,
        url: '/:slug?section',
        onEnter: function($stateParams) {
            // Works, as state has been reloaded.
            console.log('$stateParams', $stateParams);
        },

        views: {
            'main': {
                controller: 'TopicCtrl',
                templateUrl: 'topics/templates/details.tpl.html'
            },
            'sidebar': {
                controller: 'SidebarCtrl',
                templateUrl: 'topics/templates/sidebar.tpl.html'
            }
        }

для более подробной информации → https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views