Javascript Angular 2 如何使用路由器和 location.go() 检测后退按钮按下?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39132737/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular 2 How to detect back button press using router and location.go()?
提问by Adrian Moisa
I have built an app that uses router 3.0.0-beta.1
to switch between app sections. I also use location.go()
to emulate the switch between subsections of the same page. I used <base href="/">
and a few URL rewrite rules in order to redirect all routes to index.html
in case of page refresh. This allows the router to receive the requested subsection as a URL param. Basically I have managed to avoid using the HashLocationStrategy
.
我构建了一个router 3.0.0-beta.1
用于在应用程序部分之间切换的应用程序。我还location.go()
用来模拟同一页面的小节之间的切换。我使用<base href="/">
了一些 URL 重写规则,以便index.html
在页面刷新时将所有路由重定向到。这允许路由器接收请求的子部分作为 URL 参数。基本上我已经设法避免使用HashLocationStrategy
.
routes.ts
路由.ts
export const routes: RouterConfig = [
{
path: '',
redirectTo: '/catalog',
pathMatch: 'full'
},
{
path: 'catalog',
component: CatalogComponent
},
{
path: 'catalog/:topCategory',
component: CatalogComponent
},
{
path: 'summary',
component: SummaryComponent
}
];
If I click on a subsection in the navigation bar 2 things happen:
如果我点击导航栏中的一个小节,会发生两件事:
logation.go()
updates the URL with the necessary string in order to indicate the current subsection- A custom
scrollTo()
animation scrolls the page at the top of the requested subsection.
logation.go()
使用必要的字符串更新 URL 以指示当前子节- 自定义
scrollTo()
动画在请求的子部分顶部滚动页面。
If I refresh the page I am using the previously defined route and extract the necessary parameter to restore scroll to the requested subsection.
如果我刷新页面,我将使用先前定义的路由并提取必要的参数以恢复滚动到请求的子部分。
this._activatedRoute.params
.map(params => params['topCategory'])
.subscribe(topCategory => {
if (typeof topCategory !== 'undefined' &&
topCategory !== null
) {
self.UiState.startArrowWasDismised = true;
self.UiState.selectedTopCategory = topCategory;
}
});
All works fine except when I click the back button. If previous page was a different section, the app router behaves as expected. However if the previous page/url was a subsection, the url changes to the previous one, but nothing happens in the UI. How can I detect if the back button was pressed in order to invoke the scrollTo()
function to do it's job again?
一切正常,除非我单击后退按钮。如果上一页是不同的部分,则应用路由器会按预期运行。但是,如果前一个页面/url 是一个子部分,则 url 会更改为前一个,但 UI 中不会发生任何事情。我如何检测是否按下了后退按钮以调用该scrollTo()
函数再次完成它的工作?
Most answers I saw relly on the event onhashchange
, but this event does not get fired in my app since I have no hash in the URL afterall...
我看到的大多数答案都依赖于该事件onhashchange
,但是此事件不会在我的应用程序中被触发,因为毕竟我在 URL 中没有哈希值...
回答by VSO
I don't know if the answers are dated, but neither of them worked well for me in Angular 7. What I did was add an Angular event listener by importing it into my component:
我不知道答案是否过时,但它们在 Angular 7 中都不适合我。我所做的是通过将其导入到我的组件中来添加一个 Angular 事件侦听器:
import { HostListener } from '@angular/core';
and then listening for popstate
on the window
object (as Adrian recommended):
然后监听popstate
上window
的对象(如阿德里安推荐):
@HostListener('window:popstate', ['$event'])
onPopState(event) {
console.log('Back button pressed');
}
This worked for me.
这对我有用。
回答by Jon Black
Another alternative for this issue would be to subscribe to the events emitted by the Angular Router service. Since we are dealing with routing, it seems to me that using Router events makes more sense.
此问题的另一种选择是订阅Angular Router 服务发出的事件。由于我们正在处理路由,在我看来使用 Router 事件更有意义。
constructor(router: Router) {
router.events
.subscribe((event: NavigationStart) => {
if (event.navigationTrigger === 'popstate') {
// Perform actions
}
});
}
I would like to note that popstate
happens when pressing back and forward on the browser. So in order to do this efficiently, you would have to find a way to determine which one is occurring. For me, that was just using the event
object of type NavigationStartwhich gives information about where the user is coming from and where they are going to.
我想指出,popstate
在浏览器上按后退和前进时会发生这种情况。因此,为了有效地执行此操作,您必须找到一种方法来确定正在发生的是哪一个。对我来说,那只是使用NavigationStartevent
类型的对象,它提供有关用户来自哪里以及他们要去哪里的信息。
回答by Shivakumar NH
To detect browser back button click import platformlocation from '@angular/common and place the below code in your constructor :
要检测浏览器后退按钮,请单击 import platformlocation from '@angular/common 并将以下代码放入您的构造函数中:
constructor(location: PlatformLocation) {
location.onPopState(() => {
alert(window.location);
}); }
回答by Rmalmoe
Angular documentation states directly in PlatformLocation class...
Angular 文档直接在 PlatformLocation 类中声明...
- This class should not be used directly by an application developer.
- 应用程序开发人员不应直接使用此类。
I used LocationStrategy in the constructor
我在构造函数中使用了 LocationStrategy
constructor(location: LocationStrategy) {
location.onPopState(() => {
alert(window.location);
});
}
回答by Ryann Galea
A great clean way is to import 'fromEvent' from rxjs and use it this way.
一个非常干净的方法是从 rxjs 导入 'fromEvent' 并以这种方式使用它。
fromEvent(window, 'popstate')
.subscribe((e) => {
console.log(e, 'back button');
});
回答by vanrado
I agree with Adrian Moisa answer,
我同意 Adrian Moisa 的回答,
but you can use "more Angular 2 way" using class PlatformLocationby injecting to your component or service, then you can define onPopState callback this way:
但是您可以通过注入到您的组件或服务中使用类PlatformLocation来使用“更多 Angular 2 方式” ,然后您可以通过这种方式定义 onPopState 回调:
this.location.onPopState(()=>{
// your code here...
this.logger.debug('onpopstate event');
});
回答by Adrian Moisa
Using onpopstateevent did the trick:
使用onpopstate事件可以解决问题:
window.addEventListener('popstate',
// Add your callback here
() => self.events.scrollToTopCategory.emit({ categId: self.state.selectedTopCategory })
);