6

我正在使用Angular 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 使用了多个嵌套视图,我会尽力说明

索引.html

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

/静态/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

现在是让我把头发扯掉的部分。

我回到路由的阅读器部分中的“解决”代码块。

警报消息出现两次。

通过在 Web 控制台中进行一些调试,我发现订单正常

 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() 在幕后做的事情,并构建了网址。

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

3 回答 3

1

我遇到了这个问题,发现这是因为我在代码的其他地方手动调用了我的解析函数。搜索您的代码panelContent(),您可能会发现它再次被触发的位置。

于 2016-04-28T23:16:52.373 回答
0

我有同样的错误。我发现我$stateParams在其中一个解析函数中发生了变化。解决方案是从此对象制作副本,然后使用副本执行您想要的操作。

resolve: {

      /** @ngInject */
      searchParams: function ($stateParams) {
        let params = angular.copy($stateParams); // good

        // good: 
        if (params.pending === undefined) {
          params.pending = true;
        }

        // bad: 
        if ($stateParams.redirect === 'true') {
          $stateParams.pending = false; // this line changing the URL
        }
        return params;
      },

}

于 2019-04-29T22:04:53.823 回答
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两枪。

于 2017-07-21T10:05:23.607 回答