mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
fix($location): do not $digest if browser's url change fired within $apply/$digest
Chrome (probably other browsers as well) fires 'hashchange' event synchronously, so if you change raw location from within $apply/$digest, we don't want to $apply twice. (It would throw an exception)
This commit is contained in:
parent
5cdfe45aa3
commit
c49b8a2db5
2 changed files with 41 additions and 2 deletions
|
|
@ -530,8 +530,10 @@ function $LocationProvider(){
|
|||
// update $location when $browser url changes
|
||||
$browser.onUrlChange(function(newUrl) {
|
||||
if (currentUrl.absUrl() != newUrl) {
|
||||
currentUrl.$$parse(newUrl);
|
||||
$rootScope.$apply();
|
||||
$rootScope.$evalAsync(function() {
|
||||
currentUrl.$$parse(newUrl);
|
||||
});
|
||||
if (!$rootScope.$$phase) $rootScope.$digest();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -364,6 +364,43 @@ describe('$location', function() {
|
|||
}));
|
||||
|
||||
|
||||
// location.href = '...' fires hashchange event synchronously, so it might happen inside $apply
|
||||
it('should not $apply when browser url changed inside $apply', inject(
|
||||
function($rootScope, $browser, $location) {
|
||||
var OLD_URL = $browser.url(),
|
||||
NEW_URL = 'http://updated.com/url';
|
||||
|
||||
|
||||
$rootScope.$apply(function() {
|
||||
$browser.url(NEW_URL);
|
||||
$browser.poll(); // simulate firing event from browser
|
||||
expect($location.absUrl()).toBe(OLD_URL); // should be async
|
||||
});
|
||||
|
||||
expect($location.absUrl()).toBe(NEW_URL);
|
||||
}));
|
||||
|
||||
// location.href = '...' fires hashchange event synchronously, so it might happen inside $digest
|
||||
it('should not $apply when browser url changed inside $digest', inject(
|
||||
function($rootScope, $browser, $location) {
|
||||
var OLD_URL = $browser.url(),
|
||||
NEW_URL = 'http://updated.com/url',
|
||||
notRunYet = true;
|
||||
|
||||
$rootScope.$watch(function() {
|
||||
if (notRunYet) {
|
||||
notRunYet = false;
|
||||
$browser.url(NEW_URL);
|
||||
$browser.poll(); // simulate firing event from browser
|
||||
expect($location.absUrl()).toBe(OLD_URL); // should be async
|
||||
}
|
||||
});
|
||||
|
||||
$rootScope.$digest();
|
||||
expect($location.absUrl()).toBe(NEW_URL);
|
||||
}));
|
||||
|
||||
|
||||
it('should update browser when $location changes', inject(function($rootScope, $browser, $location) {
|
||||
var $browserUrl = spyOnlyCallsWithArgs($browser, 'url').andCallThrough();
|
||||
$location.path('/new/path');
|
||||
|
|
|
|||
Loading…
Reference in a new issue