Angular 4 如何阻止Header组件在页面切换时重新加载
Hey there! Let's tackle that frustrating marquee reset problem you're facing. The core issue here is your <page-header> component is getting destroyed and recreated every time you switch routes—this is why the marquee scroll position resets completely. Here are a few practical solutions to fix this:
1. Move the Header Outside the Router Outlet (Simplest Fix)
The most straightforward way to keep your Header stable is to render it once outside your app's router outlet instead of including it in each page's template. This way, it never gets destroyed during route changes.
Update your root component template (usually app.component.html):
<!-- Header stays here, initialized once --> <page-header></page-header> <!-- Router outlet handles page content switching --> <router-outlet></router-outlet>
Remove <page-header></page-header> from all individual page templates. This ensures your marquee (and the entire Header) stays alive and maintains its state across route changes.
2. Persist Marquee Scroll Position with a Service (If You Can't Move the Header)
If for some reason you need to keep the Header inside routed components, you can use a shared service to save and restore the marquee's scroll position.
Step 1: Create a Marquee State Service
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class MarqueeStateService { // Store the last scroll position of the marquee savedScrollPosition = 0; }
Step 2: Update the Header Component
Add template references and lifecycle hooks to save/restore the scroll position:
import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core'; import { MarqueeStateService } from './marquee-state.service'; @Component({ selector: 'page-header', templateUrl: './page-header.component.html' }) export class PageHeaderComponent implements OnInit, OnDestroy { // Get a reference to the marquee element @ViewChild('marqueeElement') marqueeElement!: ElementRef<HTMLMarqueeElement>; constructor(private marqueeState: MarqueeStateService) {} ngOnInit() { // Restore the saved scroll position when the component initializes if (this.marqueeElement.nativeElement && this.marqueeState.savedScrollPosition > 0) { this.marqueeElement.nativeElement.scrollLeft = this.marqueeState.savedScrollPosition; } } ngOnDestroy() { // Save the current scroll position before the component is destroyed if (this.marqueeElement.nativeElement) { this.marqueeState.savedScrollPosition = this.marqueeElement.nativeElement.scrollLeft; } } }
Step 3: Add the Template Reference to Your HTML
<div class="row page-header"> <div class="col-sm-3 align-left"> <img class="customer-logo" [src]="_DomSanitizationService.bypassSecurityTrustUrl('data:image/jpg;base64,'+ kioskservice.getLogo())"/> </div> <div class="col-sm-6 align-center"> <!-- Add the #marqueeElement reference here --> <marquee #marqueeElement direction="left" scrollamount="5" behavior="scroll"> {{translationservice.getExpression("Appointment.AddEdit_PostalCodeServiceError")}} </marquee> </div> <div class="col-sm-3 align-right"> <i class="far fa-clock"></i>{{ clockservice.time | date:"HH:mm" }} </div> </div>
3. Replace Native Marquee with a Custom CSS/JS Scroll (More Reliable)
Note that the native <marquee> tag is actually deprecated in HTML5. For better control and compatibility, consider replacing it with a custom CSS animation. This makes it easier to manage scroll state and avoids browser inconsistencies.
Example CSS Scroll
.marquee-container { overflow: hidden; white-space: nowrap; width: 100%; } .marquee-content { display: inline-block; animation: scroll-left 20s linear infinite; } @keyframes scroll-left { from { transform: translateX(100%); } to { transform: translateX(-100%); } }
Updated HTML
<div class="col-sm-6 align-center marquee-container"> <div class="marquee-content"> {{translationservice.getExpression("Appointment.AddEdit_PostalCodeServiceError")}} </div> </div>
With this setup, you can pause/resume the animation or adjust the transform value directly using your state service if needed.
内容的提问来源于stack exchange,提问作者Mex

