Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修改 URL 参数,而不重新刷新视图的方法 #3

Open
meetbill opened this issue Sep 15, 2020 · 0 comments
Open

修改 URL 参数,而不重新刷新视图的方法 #3

meetbill opened this issue Sep 15, 2020 · 0 comments

Comments

@meetbill
Copy link
Owner

meetbill commented Sep 15, 2020

缘起

当 url 有参数时,使用 $state.go 切换时,会调用两次 controller

这个会调用两次的问题,看 ui-router 上有很多相关 issue,不过在我这里的触发的原因和他们不一样,这里是我使用了分页才会触发这个问题,而且触发的时候,是因为如下代码

代码(本意时,如果浏览器传了 page_index 参数,就将$scope.currentPage 设置为浏览器传的参数 )

var params = {};
if ($stateParams.page_index) {
    params['page_index'] = $stateParams.page_index;
    //$scope.currentPage = $stateParams.page_index;   ==== 就这行,加上就会触发两次,不加就只触发 1 次
}
else
{
    params['page_index'] = 1;
}

但是不加的话,在通过浏览器刷新页面或者往前以及往后翻页,下面【页面按钮】显示不正确

整体代码

'use strict';

var app = angular.module('app');
app.controller('CanghaiMQJobsCtrl', ['$scope', 'Request', '$stateParams', '$httpParamSerializer', '$state', '$location', '$window',
function($scope, Request, $stateParams, $httpParamSerializer, $state, $location, $window){
    console.log("ceshi 1")
    $scope.itemsPerPage = 15;

    var params = {};
    if ($stateParams.page_index) {
        params['page_index'] = $stateParams.page_index;
        $scope.currentPage =  Number($stateParams.page_index);
    }
    else
    {
        params['page_index'] = 1;
        $scope.currentPage =  1;
    }

    if ($stateParams.page_size) {
        params['page_size'] = $stateParams.page_size;
    }
    else
    {
        params['page_size'] = 15;
    }

    if ($stateParams.queue_name) {
        params['queue_name'] = $stateParams.queue_name;
    }
    else
    {
        params['queue_name'] = 'default';
    }

    if ($stateParams.registry_name) {
        params['registry_name'] = $stateParams.registry_name;
    }
    else
    {
        params['registry_name'] = 'queued';
    }


    $scope.updateData=function (params){
        console.log("xxxxxxxxxxxxxxxxxxxxxxxxxxx")
        console.log(params)
        Request.get('/canghai/list_jobs?' + $httpParamSerializer(params),function(res){
            $scope.jobs = res.data.jobs;
            $scope.queueName = res.data.name;
            $scope.registryName = res.data.registry_name;
            $scope.totalItems = res.data.total_items;
        }, false, true);
    }

    $scope.updateData(params)

    $scope.pageChanged = function() {
        console.log("--------------------------")
        params['page_index'] = String($scope.currentPage);
        $state.go('app.canghai.mq_jobs', params,  {notify: false});
        $scope.updateData(params)
    };

}]);

问题

  • 当页码传 1 时,只执行 1 次后端请求
  • 当页码传非 1 时,比如页码传 3,执行了 3 次后端请求
    • (1) 刷新视图,页码传的 1
    • (2) 刷新视图,页码传的 3
    • (3) 执行了 pageChanged (ng-change)

传送门

$ urlRouterProvider负责监视$ location。当$ location更改时,它将逐一遍历规则列表,直到找到匹配项。 https://github.com/angular-ui/ui-router/wiki/URL-Routing

reloadOnSearch angular-ui/ui-router#1079

【ui-sref initialze controller twice if url has params】 angular-ui/ui-router#1476

解决方法

方法 1(个人推荐)

https://qa.1r1g.com/sf/ask/1650954581/

$state.go('.detail', {id: newId}, {notify: false}) 

$state.go(to,params,options);

to:string,即将跳转的状态。
params:object,跳转所带的参数。
options:object,可选配置对象。
    location(是否更新地址栏的url,或以什么字符串替换url),
    inherit(是否继承当前url的参数)
    relative(当变化相对路径:如"^,定义的状态是相对的)
    notify(是否广播$stateChangeStart和$stateChangeSuccess事件)
    reload(是否重新载入)。

遗留问题

使用此方式的逻辑如下

点击切换页面

(1) $state.go() 切到新 URL,因为 notify 为 false,所以不更新视图,在函数中进行更新数据
(2) 假设切换页从 1->2->3->4,点击浏览器返回页时

4->3 :这个时候出发浏览器 url 变化,导致重新刷新视图,会先更新为第 3 页,再更新为第 1 页

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant