3

Я использую angular ui router для обработки маршрутизации на моем интерфейсе. Вот как выглядит мой код маршрутизации.«Устранение» углового UI маршрутизатора срабатывает дважды

// angular config 

$stateProvider.state('app', { 
    templateUrl: '/static/partials/home.html', 
    controller: 'NavCtrl' 
}); 

$stateProvider.state('app.reader', { 
    url : '/reader/*path?start&end&column&page', 
    templateUrl: '/static/partials/reader.html', 
    resolve : { 
     panelContent : [ 
      '$state', '$stateParams', '$http', 
      function ($state, $stateParams, $http) { 
       alert('resolving panel Content'); 
       return []; // simplest thing possible to illustrate my point 
      } 
     ] 
    }, 
    controller: 'ReaderCtrl' 
}); 

/// etc etc 

$urlRouterProvider.otherwise('/reader/'); 

Мой HTML использует несколько вложенных представлений, я постараюсь показать, насколько я могу

index.html

<html> 
    <div ui-view></div>  <!-- /static/partials/home.html gets injected here --> 
</html> 

/static/home.html

<html> 
    <!-- some side bar stuff --> 

    <!-- reader --> 
    <div ui-view></div> <!-- /static/partials/reader.html gets injected here --> 
</html> 

Итак, у меня есть несколько уровней гнездования

-- index.html 
    -- home.html 
     -- reader.html 

Теперь, когда я загрузить страницу в первый раз, мое предупредительное сообщение

alert('resolving panel Content'); 

пожары только один раз .. это имеет смысл. Однако, скажем, я нажимаю «следующую страницу» в моей пагинации ..

<!-- inside /static/partials/reader.html --> 

<uib 
    pagination total-items= "totalItems" 
    ng-model= "pageNumber" 
    ng-change= "pageUpdate" 
    max-size= "maxPageNumbersDisplayed" 
></uib> 

это в конечном итоге пожары функции внутри моего «ReaderCtrl»

$scope.pageUpdate(page) { 
    $state.go('.', {page: page}); 
} 

Это обновляет URL, от перехода к чему-то вроде этого

/#/reader/<my path> 

к чему-то вроде этого

/#/reader/<my_path>?page=2 

Теперь для той части, которая меня разрывает мои волосы.

Я возвращаюсь к блоку кода «разрешить» в разделе чтения моей маршрутизации.

Предупреждающее сообщение происходит дважды.

Делая немного отладки в веб-консоли, я обнаружил, что порядок идет

1) alert message in resolve 
2) travel through the entirety of ReaderCtrl 
3) lots and lots of angular calls 
4) alert message (2nd time) 
5) travel through entirety of ReaderCtrl a second time. 

Вы можете быть склонны знать, что происходит в NavCtrl, но я не делаю никаких звонков там. Все, что находится в NavCtrl, - это функции, которые ReaderCtrl может наследовать, чтобы обновить область /static/partials/home.html

Так что, похоже, что я застрял на шаге 3 здесь.

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

редактировать:

после немного больше отладки, я, казалось, чтобы выяснить, что порядок идет что-то вроде этого, начиная сразу после функции «updatePage» выполняет.

1) first "resolving message" 
    -- the url has not yet changed 
2) second "resolving message" 
    -- the url appears to have changed very shortly before this message 

Итак, я думаю, мой вопрос сейчас ... почему

$state.go('.', args); 

НЕ изменить URL перед первым пожарам оповещения, но изменить URL в/вблизи второго предупреждения?

Редактировать 2: не удалось закончить исправление моей проблемы, так что пока я немного взломал его ... Я по существу сделал функцию, которая сделала то, что я предполагаю, что $ state.go() делал за кулисами , и построил url.

function _mk_url(args) { 

    var url = "/reader"; 

    var pageNumber = args.pageNumber || 1; 
    url += "?page=" + pageNumber; 

    var columns = args.columns || []; 
    columns.forEach(function(d) { 
     url += "&column=" + d; 
    }); 

    //etc.. 

    return url; 
} 

var args = {"columns" : ["a", "b", "c"], "pageNumber" : 2}; 
var url = _mk_url(args); 
$location.url(url); 
+0

Сразу же после чтения я предполагаю, что проблема связана с изменением состояния в 'ReaderCtrl', и она является рендерингом. Затем он снова решает маршрут, чтобы получить параметры маршрута. – ryan0319

+0

Я добавил еще несколько предупреждающих строк, и я узнал, что 1) первое решение называется 2), тогда URL-адрес изменяется 3) запускается следующее разрешение. Таким образом, кажется, что первый $ state.go (...) запускает маршрут/разрешение, фактически не изменяя путь. Затем, когда путь ACTUALLY изменяется, разрешение снова запускается. – Zack

+0

https://github.com/angular-ui/ui-router/wiki#resolve Пробовал ли вы использовать '$ stateChangeSuccess', который запускается только после? – ryan0319

ответ

1

У меня возникла эта проблема и выяснилось, что это было потому, что я вручную вызывал функцию разрешения в другом месте в коде. Найдите свой код для panelContent(), и вы можете найти, где он снова запускается.

0

У меня была эта проблема. Причина была в моем html-шаблоне. Я использовал ui-sref директиву в обоих дочерних и родительских элементов

<li ui-sref="{{r.name}}" ng-class="vm.isCurrent(r)" ng-repeat="r in vm.settingsRoutes"> <span ui-sref="{{r.name}}" ng-bind-html="r.title"></span> </li>

поэтому, когда я нажал на span, я обожженных stateChange дважды.

Смежные вопросы