Angular:如何从endlessblow组件获取app.component中<app-footer>的高度
Hey Andrzej,
Since <app-footer> resides in app.component.html (your root/parent component) instead of being a direct child of endlessblow.component.html, @ViewChild can't reach it—it only targets elements within the current component's template. No need to rearrange your footer though; here are two reliable Angular-native approaches to get that reference:
Solution 1: Use a Shared Service (Best for Non-Directly Related Components)
A shared service is Angular's go-to pattern for sharing data or component references across components that don't have a direct parent-child link. Here's how to set it up:
Step 1: Create the Shared Service
import { Injectable } from '@angular/core'; import { FooterComponent } from './path-to-footer/footer.component'; @Injectable({ providedIn: 'root' }) export class FooterReferenceService { private footerInstance: FooterComponent | null = null; // Set the footer reference from the parent component setFooterRef(footer: FooterComponent): void { this.footerInstance = footer; } // Retrieve the reference in your endlessblow component getFooterRef(): FooterComponent | null { return this.footerInstance; } }
Step 2: Inject and Set the Reference in AppComponent
import { Component, ViewChild, AfterViewInit } from '@angular/core'; import { FooterComponent } from './path-to-footer/footer.component'; import { FooterReferenceService } from './footer-reference.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent implements AfterViewInit { @ViewChild(FooterComponent) private footer!: FooterComponent; constructor(private footerService: FooterReferenceService) {} ngAfterViewInit(): void { // Pass the footer reference to the service once the view is initialized this.footerService.setFooterRef(this.footer); } }
Step 3: Retrieve the Reference in EndlessblowComponent
import { Component, AfterViewInit } from '@angular/core'; import { FooterReferenceService } from './footer-reference.service'; import { FooterComponent } from './path-to-footer/footer.component'; @Component({ selector: 'app-endlessblow', templateUrl: './endlessblow.component.html' }) export class EndlessblowComponent implements AfterViewInit { private footerRef: FooterComponent | null = null; constructor(private footerService: FooterReferenceService) {} ngAfterViewInit(): void { // Get the footer reference from the service this.footerRef = this.footerService.getFooterRef(); // Now you can interact with the footer (e.g., call methods, access properties) if (this.footerRef) { // Example: this.footerRef.scrollToTop(); } } }
Solution 2: Pass the Reference via Input (Simple for Direct Parent-Child)
If <app-endlessblow> is already a direct child of app-root, you can skip the service and pass the footer reference directly via an input property:
Step 1: Add an Input Property to EndlessblowComponent
import { Component, Input } from '@angular/core'; import { FooterComponent } from './path-to-footer/footer.component'; @Component({ selector: 'app-endlessblow', templateUrl: './endlessblow.component.html' }) export class EndlessblowComponent { @Input() footerRef!: FooterComponent; // Use the reference anywhere in the component interactWithFooter(): void { if (this.footerRef) { // Your logic here } } }
Step 2: Pass the Reference from app.component.html
Use a template variable to grab the footer instance and pass it to your endlessblow component:
<app-endlessblow [footerRef]="footer"></app-endlessblow> <app-footer #footer></app-footer>
Key Reminder
Always access the footer reference in the ngAfterViewInit lifecycle hook (not ngOnInit) to ensure the component's view has fully loaded and the reference is valid. If your footer is ever destroyed dynamically, remember to null out references to avoid memory leaks.
内容的提问来源于stack exchange,提问作者user14892464

