LoginSignup
1
1

More than 5 years have passed since last update.

[AngularJS] $locationのpushStateでクエリパラメータを変更するService(自作)

Last updated at Posted at 2016-02-24

取り急ぎソースだけ。

pushState / popStateの動作なので、ブラウザの戻る/進むなどにも反応して、クエリパラメータの変更を検知できる。

現状、パラメータは一つしか変更対象にできないが、複数に対応できると思う。

html5Modeがオフだと動かないのどうしようかなあ。

js

var app = angular.module('app', []);

app.provider('queryChanger', function() {
    var paramName = 'page';

    this.setParamName = function( _paramName ) {
        paramName = _paramName;
    };

    this.$get = [ '$location', '$rootScope', function( $location, $rootScope ) {

        // ページ表示時、強制的に対象のクエリパラメータを付加する
        if( $location.search()[paramName] == null ) {
            var query = $location.search();
            query[paramName] = 0;
            $location.search( query ).replace();
        }

        // $locationのルーティング支配下から強引に脱出する
        $rootScope.$on('$locationChangeStart', function( event, newUrl, oldUrl ) {
            var before = document.createElement('a');
            before.href = oldUrl;

            var after = document.createElement('a');
            after.href = newUrl;

            if( before.pathname != after.pathname ) {
                window.location.href = newUrl;
                event.preventDefault();
            }
        });

        $rootScope.$on('$locationChangeSuccess', function() {
            $rootScope.$broadcast('queryChanged', $location.search()[paramName] );
        });

        return {
            change: function( paramValue ) {
                var query = $location.search();
                query[paramName] = paramValue;
                $location.search( query );
            }
        };
    }];
});

// --- 使い方サンプル --- //

// まずコンフィグします
app.config( [ '$locationProvider', 'queryChangerProvider', function( $locationProvider, queryChangerProvider ) {
    $locationProvider.html5Mode({
        enabled: true,
        requireBase: false
    });

    queryChangerProvider.setParamName( 'p' );
}]);

// 使います
app.controller('myController', function( $location, $scope, queryChanger ) {
    var _this = this;

    // クエリパラメータを変更する
    this.next = function() {
        queryChanger.change( _this.p + 1 );
    };

    // クエリパラメータが変更されたとき
    // 最初のページ表示時にもここが発火します
    $scope.$on('queryChanged', function( event, value ) {
        _this.p = Number( value );
    });
});

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1