Angular 4 - @ViewChild组件未定义

时间:2017-08-16 09:21:35

标签: angular typescript angular-components

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

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

内的

<router-outlet>

export class UserManagementComponent implements OnInit {

  @ViewChild(ToastComponent) toast: ToastComponent;

  constructor() {}

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

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

如果我从<llqa-toast></llqa-toast>中取出app.component.html并将其放在user-management.component.html之上,它可以正常工作,但我必须将其放在每个组件中。我怎样才能让它发挥作用?

1 个答案:

答案 0 :(得分:3)

因为在您的情况下,ToastComponent用于父母(AppComponent),这就是您收到此错误的原因。避免此错误的一种方法是使用某些共享服务中定义的Subject。我在我的项目中使用该方法来显示吐司通知。以下是如何做到这一点:

<llqa-toast></llqa-toast>保持在app.component.html

定义服务以基本上发出事件并在ToastComponent中订阅该事件。例如,

  

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);
    }
}

您需要在AppModule提供商中注入此服务。现在subscribe发送OnShowToast中的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
  }
}

现在,您可以从所需的任何组件中调用showToast()的{​​{1}}方法。例如,

  

UserManagementComponent

UtilityService