首页 > 解决方案 > 当我使用 @ViewChild 在 Angular 组件之间共享布尔数据时,我得到未定义的属性

问题描述

我有一个名为 的组件RedirectUserToMobileAppComponent,我想从中共享一个名为 的布尔enableLoginForm属性app.component。当我执行时,我得到这个错误:

enableLoginForm是app.componentngAfterViewInit上的未定义属性

这是RedirectUserToMobileAppComponent组件:

    import {
        Component,
        ComponentFactoryResolver,
        ComponentRef,
        Inject,
        Input,
        OnInit,
        Output,
        ViewChild,
        ViewContainerRef,
    } from '@angular/core';
    import { Observable, Subscription } from 'rxjs';
    import { filter, map, pluck, tap } from 'rxjs/operators';
    import { ActivatedRoute, Router } from '@angular/router';
    import { MAT_DIALOG_SCROLL_STRATEGY_FACTORY } from '@angular/material/dialog';

    @Component({
        selector: 'redirect-user-to-mobile-app',
        templateUrl: './redirect-user-to-mobile-app.component.html',
        styleUrls: ['./redirect-user-to-mobile-app.component.sass'],
    })
    export class RedirectUserToMobileAppComponent implements OnInit {
        constructor(
        ) {}
        enableLoginForm = false;
        ngOnInit(): void {}
    
        OnLogin(): void {
            this.enableLoginForm = true;
            this.router.navigate(['../login']);
        }
        
    }

这是app.component

    import {
    Component,
    HostListener,
    OnDestroy,
    OnInit,
    ViewChild,
    AfterViewInit,
} from '@angular/core';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import { FirebaseService } from './services/firebase/firebase.service';
import {
    SnakeMessage,
    SnakeMessageService,
} from './services/snakeMessage/snakeMessage.service';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Subscription } from 'rxjs';
import { StorageService } from './services/storage/storage.service';
import { AuthService } from './services/auth/auth.service';
import { RedirectUserToMobileAppComponent } from './redirect-user-to-mobile-app/redirect-user-to-mobile-app.component';

@Component({
    selector: 'app-component',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
    favIcon: HTMLLinkElement = document.querySelector('#appIcon');
    private snakeMessageSub: Subscription;
    isLoading = true;
    isLogged: boolean;

    @ViewChild(RedirectUserToMobileAppComponent)
    redirectComponent!: RedirectUserToMobileAppComponent;

    constructor(
        private matIconRegistry: MatIconRegistry,
        private firebaseService: FirebaseService,
        private snakeMessageService: SnakeMessageService,
        private _snackBar: MatSnackBar,
        private storageService: StorageService,
        private domSanitizer: DomSanitizer,
        private authService: AuthService
    ) {
        this.registerCustomIcons();
        this.storageService.initDB();
        this.storageService.onLoaded$.subscribe((loaded) => {
            if (loaded) {
                this.isLoading = false;
            }
        });
        this.isLogged = this.authService.isLoggedIn;
    }

    ngAfterViewInit() {
        if (this.redirectComponent.enableLoginForm) {
            this._is = this.redirectComponent.enableLoginForm;
        }
    }

    ngOnInit(): void {
        this.snakeMessageSub = this.snakeMessageService.messageSub.subscribe(
            (snakeMessage: SnakeMessage) => {
                this._snackBar.open(snakeMessage.message, snakeMessage.action, {
                    duration: 3000,
                    horizontalPosition: 'center',
                    verticalPosition: 'top',
                });
            }
        );
    }

这是我的 app.component.html

<ng-container *ngIf="!isLoading">
<ng-container *ngIf="isMobileDevice() && !isLogged">
    <redirect-user-to-mobile-app> </redirect-user-to-mobile-app>
    <router-outlet
        *ngIf="enableLoginForm"
    ></router-outlet>
</ng-container>

<router-outlet *ngIf="!isMobileDevice()"></router-outlet>

标签: htmlangulartypescriptfrontendangular-components

解决方案


这是您使用 ViewChild 的方式:

@ViewChild('templateId', { static: false }) redirectComponent: RedirectUserToMobileAppComponent;

您应该在模板部分设置了 templateId:

<redirect-user-to-mobile-app #templateId> ... </redirect-user-to-mobile-app>

编辑:虽然我同意天蓝,但您应该使用服务在组件之间共享数据


推荐阅读