提问人:Issac Howard 提问时间:10/30/2023 更新时间:11/3/2023 访问量:45
了解 Angular 中的异步订阅
Understanding asynchronicity Subscriptions in Angular
问:
我觉得我的问题与异步编程有关,因为当我想要它时没有运行。我通常将我的问题分为用户的角度和开发人员的视角。subscription
用户视角:
当用户位于主页上并单击“主页”导航按钮时,网站将刷新。用户不觉得这有吸引力,并希望它,因为如果用户在主页上并点击主页,那么什么都不会发生。导航图片如下。如果用户在主页之外,那么(显然)如果他们单击主页,那么他们应该被重定向到主页。
开发者观点:
在模板初始化期间,代码将检查路由器 URL 是否为 。如果是,则 href 应等于 ,如果不是,则 href 应等于 。下面提供了注释代码。/en/home
/en/home
#
/en/home
杂项服务:
// service that does miscellaneous things, one of which is just detecting a url change
@Injectable({
providedIn: 'root'
})
export class MiscellaneousService {
urlChange = new Subject<string>()
// other properties & methods
}
标头 TS 组件:
export class HomeHeaderComponent implements OnInit {
currentURL: string = ''
isHomeRoute: boolean = true
constructor(private misService: MiscellaneousService, private router: Router) {}
ngOnInit(): void {
/*
IMPORTANT READ:
on every page, we will do a 'urlChange.next()' method to ensure the currentURL is updated.
I would suppose that the urlChange.next(this.router.url) works but what I am sure of is that the
subscription does not work as currentURL is always an empty string. I would suppose that this has
to do with the asyncronousity of subscribe and when it runs. If that is the case, how can I fix this so that
the component is always updated to the current URL the user is on?
*/
this.misService.urlChange.next(this.router.url)
this.misService.urlChange.subscribe(currentURL => {
this.currentURL = currentURL
})
console.log(this.currentURL)
if (this.currentURL == '/en/home') {
this.isHomeRoute = true
}
else {
this.isHomeRoute = false
}
}
那么我怎样才能做到,以便我们订阅任何更改?我需要更改什么?router.url
有关更多参考,下面是模板中作为标题的部分
标题模板:
<a class="nav-link" [href]="isHomeRoute ? '#' : '/en/home'">
home<span class="sr-only">(current)</span>
</a>
<!-- Other code... -->
答:
1赞
NoNamer777
10/30/2023
#1
您可以观察并筛选出事件,以捕获所有成功的路由事件。router.events
NavigationEnd
router.events
.pipe(
// Only take successfull navigation events
filter((routingEvent) => routingEvent instanceof NavigationEnd),
)
.subscribe((routingEvent) => {
// Do anything with the URL at this point
console.log(routingEvent.url);
});
评论
0赞
Issac Howard
10/30/2023
非常感谢你的回答,但从何而来?我从未在我的标头组件中声明过它。this.destroy$
0赞
NoNamer777
10/30/2023
我补充说,可能是偶然的。您可以添加一个名为 Rxjs 的 Subject 的组件变量。然后,你可以调用下一个值,并在 Angular 组件的生命周期钩子中完成流。将它与此运算符结合使用,您不必担心订阅不会被取消订阅,从而在组件被销毁时导致应用程序内存泄漏。如果您的处理以其他方式取消订阅,您可以将其排除在外destroy$
OnDestroy
takeUntil
0赞
Issac Howard
10/30/2023
类型似乎有问题,您知道我该如何解决吗?它似乎是类型,所以它没有给我一个 URL 属性......如果你能告诉我如何解决它,那就太好了,如果你不能,那就不用担心了,你帮了很多忙!routingEvent
Event_2
0赞
NoNamer777
10/30/2023
尝试将其强制转换为 NavigationEnd 事件。.您需要像这样强制转换它,因为过滤器操作不会为您强制转换它,而只是返回确实是 .如果看一下声明,它是不同导航事件的类型联合,包括 NavigationEnd 事件类型。您还可以在管道链中包含来自 Rxjs 的映射运算符,如下所示:将其转换为正确的类型。这样,您就不必在订阅中进行强制转换(routingEvent as NavigationEnd).url
Event_2
Event_2
map(event => event as NavigationEnd),
评论