-
Notifications
You must be signed in to change notification settings - Fork 26.2k
feat(common): add a LocationUpgradeService to mimic AngularJS functionality #30055
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
Conversation
…of Location services Prior to this change we had a MockLocationStrategy to replace the Path and Hash Location Strategies. However, there wasn't a good way to test the PlatformLocation which is needed for doing things such as setting history.state, using back()/forward(), etc.
Previously there wasn't a way to retrieve `history.state` from the `Location` service. The only time the framework exposed this value was in navigation events. This meant if you weren't using the Angular router, there wasn't a way to get access to this `history.state` value other than going directly to the DOM. This PR adds an API to retrieve the value of `history.state`. This will be useful and needed to provide a backwards-compatible `Location` service that can emulate AngularJS's `$location` service since we will need to be able to read the state data in order to produce AngularJS location transition events. This feature will additionally be useful to any application that wants to access state data through Angular rather than going directly to the DOM APIs.
Without this change, the framework doesn't surface URL parts such as hostname, protocol, and port. This makes it difficult to rebuild a complete URL. This change provides new APIs to read these values.
…ed APIs AngularJS's `$location` service doesn't have a direct counterpart in Angular. This is largely because the `Location` service in Angular was pulled out of the `Router`, but was not purpose-built to stand on its own. This commit adds a new `@angular/common/upgrade` package with the beginnings of a new `LocationUpgradeService`. This service will more closely match the API of AngularJS and provide a way to replace the `$location` service from AngularJS.
This feature adds an `onUrlChange` to Angular's `Location` class. This is useful to track all updates coming from anywhere in the framework. Without this method, it's difficult (or impossible) to track updates run through `location.go()` or `location.replaceState()` as the browser doesn't publish events when `history.pushState()` or `.replaceState()` are run.
When using the `history` API, setting a new `state` and retrieving it does not pass a `===` test to the object used to set the state. In other words, `history.state` is always a copy. This change makes the `MockPlatformLocation` behave in the same way.
This abstract class (and AngularJSUrlCodec) are used for serializing and deserializing pieces of a URL string. AngularJS had a different way of doing this than Angular, and using this class in conjunction with the LocationUpgradeService an application can have control over how AngularJS URLs are serialized and deserialized.
c54e7f1
to
e2ce937
Compare
This commit provides a replacement for `$location`. The new service is written in Angular, and can be consumed into existing applications by using the downgraded version of the provider. Prior to this addition, applications upgrading from AngularJS to Angular could get into a situation where AngularJS wanted to control the URL, and would often parse or se rialize the URL in a different way than Angular. Additionally, AngularJS was alerted to URL changes only through the `$digest` cycle. This provided a buggy feedback loop from Angular to AngularJS. With this new `LocationUpgradeProvider`, the `$location` methods and events are provided in Angular, and use Angular APIs to make updates to the URL. Additionally, change s to the URL made by other parts of the Angular framework (such as the Router) will be listened for and will cause events to fire in AngularJS, but will no longer attempt to update the URL (since it was already updated by the Angular framework). This centralizes URL reads and writes to Angular and should help provide an easier path to upgrading AngularJS applications to Angular.
e2ce937
to
d3a87d8
Compare
private initalizing = true; | ||
private updateBrowser = false; | ||
private $$absUrl: string = ''; | ||
private $$url: string = ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we intentionally provide these $$
fields because people read from them (and so technically they're here to be interface compatible with AngularJS), I would go ahead and make them public API. We want our public API guard to ensure they're not changed without consideration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll have this discussion with Igor to see what he thinks. I'm inclined to leave it out because if people are already using TypeScript from Definitely Typed, they will not have these and would have to do casting anyway. See type definition here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. I was more thinking that we want to make sure we don't inadvertently change any of this API, but maybe having the documentation in place that the class mirrors AngularJS's interface is enough.
1d48209
to
bac2e8c
Compare
bac2e8c
to
bbb4752
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's rename some of the symbols and remove the $locationProvider and peerDep on @angular/upgrade. the rest lgtm from the api perspective.
html5Mode(mode?: any): void; | ||
} | ||
|
||
export declare class LocationUpgradeService { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename
0c8d8cf
to
768038d
Compare
768038d
to
fb54256
Compare
This feature adds an `onUrlChange` to Angular's `Location` class. This is useful to track all updates coming from anywhere in the framework. Without this method, it's difficult (or impossible) to track updates run through `location.go()` or `location.replaceState()` as the browser doesn't publish events when `history.pushState()` or `.replaceState()` are run. PR Close #30055
…0055) This abstract class (and AngularJSUrlCodec) are used for serializing and deserializing pieces of a URL string. AngularJS had a different way of doing this than Angular, and using this class in conjunction with the LocationUpgradeService an application can have control over how AngularJS URLs are serialized and deserialized. PR Close #30055
…0055) This commit provides a replacement for `$location`. The new service is written in Angular, and can be consumed into existing applications by using the downgraded version of the provider. Prior to this addition, applications upgrading from AngularJS to Angular could get into a situation where AngularJS wanted to control the URL, and would often parse or se rialize the URL in a different way than Angular. Additionally, AngularJS was alerted to URL changes only through the `$digest` cycle. This provided a buggy feedback loop from Angular to AngularJS. With this new `LocationUpgradeProvider`, the `$location` methods and events are provided in Angular, and use Angular APIs to make updates to the URL. Additionally, change s to the URL made by other parts of the Angular framework (such as the Router) will be listened for and will cause events to fire in AngularJS, but will no longer attempt to update the URL (since it was already updated by the Angular framework). This centralizes URL reads and writes to Angular and should help provide an easier path to upgrading AngularJS applications to Angular. PR Close #30055
…common Follow-up to angular#30055 to include @angular/common/upgrade in the npm package Closes angular#30116
…common Follow-up to angular#30055 to include @angular/common/upgrade in the npm package Closes angular#30116
…common Follow-up to angular#30055 to include @angular/common/upgrade in the npm package Closes angular#30116
…common Follow-up to angular#30055 to include @angular/common/upgrade in the npm package Closes angular#30116
…of Location services (angular#30055) Prior to this change we had a MockLocationStrategy to replace the Path and Hash Location Strategies. However, there wasn't a good way to test the PlatformLocation which is needed for doing things such as setting history.state, using back()/forward(), etc. PR Close angular#30055
…angular#30055) Previously there wasn't a way to retrieve `history.state` from the `Location` service. The only time the framework exposed this value was in navigation events. This meant if you weren't using the Angular router, there wasn't a way to get access to this `history.state` value other than going directly to the DOM. This PR adds an API to retrieve the value of `history.state`. This will be useful and needed to provide a backwards-compatible `Location` service that can emulate AngularJS's `$location` service since we will need to be able to read the state data in order to produce AngularJS location transition events. This feature will additionally be useful to any application that wants to access state data through Angular rather than going directly to the DOM APIs. PR Close angular#30055
Without this change, the framework doesn't surface URL parts such as hostname, protocol, and port. This makes it difficult to rebuild a complete URL. This change provides new APIs to read these values. PR Close angular#30055
…ed APIs (angular#30055) AngularJS's `$location` service doesn't have a direct counterpart in Angular. This is largely because the `Location` service in Angular was pulled out of the `Router`, but was not purpose-built to stand on its own. This commit adds a new `@angular/common/upgrade` package with the beginnings of a new `LocationUpgradeService`. This service will more closely match the API of AngularJS and provide a way to replace the `$location` service from AngularJS. PR Close angular#30055
This feature adds an `onUrlChange` to Angular's `Location` class. This is useful to track all updates coming from anywhere in the framework. Without this method, it's difficult (or impossible) to track updates run through `location.go()` or `location.replaceState()` as the browser doesn't publish events when `history.pushState()` or `.replaceState()` are run. PR Close angular#30055
…ngular#30055) When using the `history` API, setting a new `state` and retrieving it does not pass a `===` test to the object used to set the state. In other words, `history.state` is always a copy. This change makes the `MockPlatformLocation` behave in the same way. PR Close angular#30055
…gular#30055) This abstract class (and AngularJSUrlCodec) are used for serializing and deserializing pieces of a URL string. AngularJS had a different way of doing this than Angular, and using this class in conjunction with the LocationUpgradeService an application can have control over how AngularJS URLs are serialized and deserialized. PR Close angular#30055
…gular#30055) This commit provides a replacement for `$location`. The new service is written in Angular, and can be consumed into existing applications by using the downgraded version of the provider. Prior to this addition, applications upgrading from AngularJS to Angular could get into a situation where AngularJS wanted to control the URL, and would often parse or se rialize the URL in a different way than Angular. Additionally, AngularJS was alerted to URL changes only through the `$digest` cycle. This provided a buggy feedback loop from Angular to AngularJS. With this new `LocationUpgradeProvider`, the `$location` methods and events are provided in Angular, and use Angular APIs to make updates to the URL. Additionally, change s to the URL made by other parts of the Angular framework (such as the Router) will be listened for and will cause events to fire in AngularJS, but will no longer attempt to update the URL (since it was already updated by the Angular framework). This centralizes URL reads and writes to Angular and should help provide an easier path to upgrading AngularJS applications to Angular. PR Close angular#30055
…mon/upgrade package (angular#30055) PR Close angular#30055
…grade dependency (angular#30055) PR Close angular#30055
…common (angular#30117) Follow-up to angular#30055 to include @angular/common/upgrade in the npm package Closes angular#30116 PR Close angular#30117
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
This PR contains a handful of features related to location services.
Read
history.state
Previously there wasn't a way to retrieve history.state from the Location service. The only time the framework exposed this value was in navigation events. This meant if you weren't using the Angular router, there wasn't a way to get access to this history.state value other than going directly to the DOM.
This PR adds an API to retrieve the value of history.state. This will be useful and needed to provide a backwards-compatible Location service that can emulate AngularJS's $location service since we will need to be able to read the state data in order to produce AngularJS location transition events.
This feature will additionally be useful to any application that wants to access state data through Angular rather than going directly to the DOM APIs.
Read URL parts
Without this change, the framework doesn't surface URL parts such as hostname, protocol, and port. This makes it difficult to rebuild a complete URL. This change provides new APIs to read these values.
Location Upgrade (
$location
)This PR provides a replacement for
$location
. The new service is written in Angular, and can be consumed into existing applications by using the downgraded versionof the provider.
Prior to this addition, applications upgrading from AngularJS to Angular could get into a situation where AngularJS wanted to control the URL, and would often parse or serialize the URL in a different way than Angular. Additionally, AngularJS was alerted to URL changes only through the
$digest
cycle. This provided a buggy feedback loopfrom Angular to AngularJS.
With this new
LocationUpgradeProvider
, the$location
methods and events are provided in Angular, and use Angular APIs to make updates to the URL. Additionally, changes to the URL made by other parts of the Angular framework (such as the Router) will be listened for and will cause events to fire in AngularJS, but will no longer attempt
to update the URL (since it was already updated by the Angular framework).
This centralizes URL reads and writes to Angular and should help provide an easier path to upgrading AngularJS applications to Angular.