Angular 4 - @ViewChild 组件未定义 [英] Angular 4 - @ViewChild component is undefined

查看:37
本文介绍了Angular 4 - @ViewChild 组件未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 ToastComponent 的 Toast 通知组件,我想从任何其他组件调用它.我是这样实现的:

ToastComponent:

导出类 ToastComponent 实现 OnInit {构造函数(){}showToast() {//一些代码}}

app.component.html:

<llqa-header></llqa-header><div class="content-container"><main class="content-area"><llqa-toast></llqa-toast><!-- 我想调用的 ToastComponent --><路由器插座></路由器插座></main>

</llqa-main-container>

UserManagementComponent 位于 中:

导出类 UserManagementComponent 实现 OnInit {@ViewChild(ToastComponent) toast: ToastComponent;构造函数(){}someSaveMethod() {this.toast.showToast()//下面抛出错误}}

在调用 someSaveMethod() 方法时,我会得到 toast 未定义的错误.

如果我从 app.component.html 中取出 <llqa-toast></llqa-toast> 并把它放在 user-management.component.html,它工作正常,但我必须把它放在每个组件中.我怎样才能让它工作?

解决方案

由于在您的情况下,ToastComponent 用于祖父级 (AppComponent),这就是为什么你收到这个错误.避免此错误的一种方法是使用在某些共享服务中定义的 Subject.我在我的项目中使用这种方法来显示 Toast 通知.您可以这样做:

<小时>

app.component.html 中保留您的 .

定义一个服务来基本上发出一个事件并在您的 ToastComponent 中订阅该事件.例如,

<块引用>

公用事业服务:

import { Injectable } from '@angular/core';从'rxjs'导入{主题};@Injectable()导出类 UtilityService {public OnShowToast = new Subject();公共 showToast(): 无效 {this.OnShowToast.next(true);}}

您需要在您的 AppModule 提供程序中注入此服务.现在 subscribeToastComponent 中的 OnShowToast 事件.

<块引用>

吐司组件:

import { UtilityService } from './path/to/the/utility.service';导出类 ToastComponent 实现 OnInit {构造函数(私有只读实用程序服务:UtilityService){}ngOnInit() {this.utilityService.OnShowToast.subscribe(value =>{this.showToast();});}私人表演Toast(){//一些代码}}

现在,您可以从您想要的任何组件调用 UtilityServiceshowToast() 方法.例如,

<块引用>

用户管理组件

导出类 UserManagementComponent 实现 OnInit {//你现在不需要这个//@ViewChild(ToastComponent) toast: ToastComponent;构造函数(私有只读实用程序服务:UtilityService){}someSaveMethod() {this.utilityService.showToast();}}

I have a toast notification component called ToastComponent which I want to call from any other component. I implemented it like this:

ToastComponent:

export class ToastComponent implements OnInit {

  constructor() {}

  showToast() {
    // some code
  }
}

app.component.html:

<llqa-main-container>
  <llqa-header></llqa-header>
  <div class="content-container">
    <main class="content-area">
      <llqa-toast></llqa-toast> <!-- ToastComponent which I want to call -->
      <router-outlet></router-outlet>
    </main>
  </div>
</llqa-main-container>

UserManagementComponent which is inside the <router-outlet>:

export class UserManagementComponent implements OnInit {

  @ViewChild(ToastComponent) toast: ToastComponent;

  constructor() {}

  someSaveMethod() {
    this.toast.showToast() // throws error below
  }
}

On calling the someSaveMethod() method, I'll get the error that toast is undefined.

If I take <llqa-toast></llqa-toast>out of the app.component.html and put it on top of the user-management.component.html, it works fine, but then I have to put it in every component. How can I get this to work?

解决方案

Since in your case, the ToastComponent is used in the grand parent (AppComponent), that's why you are getting this error. One way to avoid this error is to use Subject defined in some shared service. I am using that approach in my project to show toast notifications. Here is how you can do it:


Keep your <llqa-toast></llqa-toast> in app.component.html.

Define a service to basically emit an event and subscribe to that event in your ToastComponent. For example,

UtilityService:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable()
export class UtilityService {

    public OnShowToast = new Subject<boolean>();

    public showToast(): void {
        this.OnShowToast.next(true);
    }
}

You need to inject this service in your AppModule providers. Now subscribe to the OnShowToast event in your ToastComponent.

ToastComponent:

import { UtilityService } from './path/to/the/utility.service';
export class ToastComponent implements OnInit {

  constructor(private readonly utilityService: UtilityService) { }

  ngOnInit() { 
     this.utilityService.OnShowToast.subscribe(value =>
        {
            this.showToast();
        });
  }

  private showToast() {
    // some code
  }
}

Now, you can call the showToast() method of the UtilityService from any component you want. For example,

UserManagementComponent

export class UserManagementComponent implements OnInit {

  // You dont need this now
  // @ViewChild(ToastComponent) toast: ToastComponent;

  constructor(private readonly utilityService: UtilityService) {}

  someSaveMethod() {
    this.utilityService.showToast();
  }
}

这篇关于Angular 4 - @ViewChild 组件未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆