Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

ngRouter: Multiple controller initialization when search changed #16632

Closed

Description

@fifonik

I'm submitting a ...

  • bug report
  • feature request
  • other

Current behavior:

Controller is initializing multiple times while search changed with ngRouter.

Expected / new behavior:

Single search change should only trigger controller initialization once.

Minimal reproduction of the problem with instructions:

index.htm

<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
	<meta charset="utf-8" />
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	<base href="/" />
	<title>ngRoute + links with #</title>
	<style>
		ul, p   { font-size: 200%;  }
		h2      { margin-bottom: 0; }
		ul, pre { margin-top: 0;    }
	</style>

	<script src="/angular/1.6.9/angular.min.js"></script>
	<script src="/angular/1.6.9/angular-route.min.js"></script>
	<script src="app.js"></script>
</head>

<body>
	<p>Click on <b>main/#a1</b> and <b>main/#a2</b> links a few times and notice that every time when address is changing 'Ctrl.init' record added to the log once.
	<br />Then click on <b>main/</b> or <b>main/#</b> link once and notice that the single click just added 3 records to the log (rouring occured 3 times and every time the controller is initialized).
	<br />There are no such issue with AngularJS 1.6.1 and below: every click to the link initializes the controller only once.</p>

	<h2>Links</h2>
	<ul>
		<li><a href="main/">main/</a></li>
		<li><a href="main/#">main/#</a></li>
		<li><a href="main/#a1">main/#a1</a></li>
		<li><a href="main/#a2">main/#a2</a></li>
	</ul>

	<h2>View</h2>
	<section id="view" ng-view=""></section>

	<h2>Log <button type="button" ng-click="$root.log.length = 0">Clear log</button></h2>
	<pre class="log" ng-bind="$root.log|json"></pre>
</body>
</html>

app.js

var log = [];

angular
	.module('app', ['ngRoute'])
	.config(Config)
	.controller('Ctrl', Ctrl)
	.run(Run)
;

Run.$inject = ['$rootScope', '$location'];
function Run($rootScope, $location){
	log.push('Run');
	$rootScope.log = log;
}

Config.$inject = ['$locationProvider', '$routeProvider'];
function Config($locationProvider, $routeProvider){
	log.push('Config');
	$locationProvider.html5Mode(true);
	$routeProvider
		.when('/main/', {
			  template: '{{ctrl.url}}'
			, controller: 'Ctrl as ctrl'
		})
		.otherwise({
			redirectTo: '/main/'
		})
	;
}

Ctrl.$inject = ['$location'];
function Ctrl($location){
	log.push('Ctrl.init');
	var vm = this;
	vm.url  = $location.url();
}

http://plnkr.co/ZjIq1gb6hKgqPrNjsKZ0

AngularJS version: 1.6.2 and above (checked with 1.6.2, 1.6.9, 1.7.1, 1.7.2). The last version that is not affected -- 1.6.1

Browser: [all]

Activity

  1. added this to the 1.7.x milestone on Jul 18, 2018
  2. self-assigned this
    on Jul 18, 2018
  3. gkalpak commented on Jul 18, 2018

    @gkalpak
    Member

    I think it is b607618 😇 Interesting that nobody complained for almost 1.5 years. This is clearly broken 😁

  4. added a commit that references this issue on Jul 19, 2018
    198c90c
  5. gkalpak commented on Jul 19, 2018

    @gkalpak
    Member

    Should be fixed by #16636. In the meantime, you can hack around the issue like this:

    myApp.decorator('$browser', $delegate => {
      const originalUrl = $delegate.url;
      $delegate.url = (...args) => {
        const result = originalUrl.apply($delegate, args);
        return angular.isString(result) ? result.replace(/#$/, '') : result;
      };
      return $delegate;
    });

    DISCLAIMER: This is a total hack, relies on private APIs and is not recommended. Use at your own risk 😁

  6. fifonik commented on Jul 19, 2018

    @fifonik
    Author

    Many thanks for prompt fix. Have not expected this.
    I should have reported it half a year ago when first discovered %-)

  7. gkalpak commented on Jul 20, 2018

    @gkalpak
    Member

    You definitely should have 😠
    I usually feel the urge to fix things that I have broken myself 😁

    This one was quite serious (combined with routing and non-trivial route initialization logic).
    Thx for reporting it.

  8. added 2 commits that reference this issue on Jul 25, 2018
    e6fa24f
    b085893
  9. added a commit that references this issue on Jul 30, 2018
    1144b1e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions