角2 @ViewChild不起作用.无法读取媒体资源的“标题"的未定义 [英] Angular 2 @ViewChild not working. Cannot Read Property "title" of Undefined

查看:74
本文介绍了角2 @ViewChild不起作用.无法读取媒体资源的“标题"的未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使使用@ViewChild导入,我也无法访问组件的属性.下面是代码.

I am unable to access the property of component even after importing with @ViewChild. Below is the code.

header.monitor.component.ts

import { AdminComponent } from 'admin/admin.component';
import { Component } from '@angular/core';
import { ViewChild, AfterViewInit } from '@angular/core';

@Component({
    selector: 'monitor-header',
    templateUrl: './header.monitor.component.html',
    styleUrls: ['./header.monitor.component.css']
})

export class HeaderMonitorComponent implements AfterViewInit {

    @ViewChild(AdminComponent) private admin: AdminComponent;

    private monitorTitle: string;

    ngAfterViewInit() {
        this.monitorTitle = this.admin.title;
    }
 }

header.monitor.component.html

<div class="text-center header h3">{{monitorTitle}}</div>

admin.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { ElementRef } from '@angular/core';

@Component({
  selector: 'monitor-admin',
  templateUrl: './admin.component.html',
  styleUrls: ['./admin.component.css']
})
export class AdminComponent {

  constructor() { }

  title = 'Header';

}

错误错误:未捕获(承诺):TypeError:无法读取未定义的属性"title" TypeError:无法读取未定义的属性"title"

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'title' of undefined TypeError: Cannot read property 'title' of undefined

帮助我解决此错误.

推荐答案

您应该检查AfterViewChecked中的@ViewChild,而不是AfterViewInit.您也可以像这样捆绑您的@angular/core导入: import { Component, ViewChild, AfterViewInit } from '@angular/core';.然后,不用实现AfterViewInit而是实现AfterViewChecked.

You should be checking for the @ViewChild in the AfterViewChecked instead of the AfterViewInit. Also you can bundle your @angular/core imports like so: import { Component, ViewChild, AfterViewInit } from '@angular/core';. Then instead of implementing AfterViewInit just implement AfterViewChecked.

这是它的外观:

import { AdminComponent } from 'admin/admin.component';
import { Component, ViewChild, AfterViewChecked } from '@angular/core';

@Component({
    selector: 'monitor-header',
    templateUrl: './header.monitor.component.html',
    styleUrls: ['./header.monitor.component.css']
})

export class HeaderMonitorComponent implements AfterViewChecked {

    @ViewChild(AdminComponent) private admin: AdminComponent;

    private monitorTitle: string;

    ngAfterViewChecked() {
        this.monitorTitle = this.admin.title;
    }
 }

一个问题:这些都是父组件,还是其中一个组件是另一个组件的子组件?我问的原因是,您可能想研究在组件之间传递该变量的另一种方法,因为这可以通过@Input或使用服务来存储和设置标头变量来实现.我希望这可以有所帮助.

One question: Are these both parent components or will one of the components be a child of the other? The reason i ask is that you may want to look into a different method of passing that variable between components as this may be achieved with an @Input or using a service to store and set the header variable. I hope this can be of some help.

要回答您的评论,您应该创建这样的服务:

To answer your comment, you should create a service like this:

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

@Injectable()
export class HeaderService {

  _title: string;

  constructor() { }

  set title(title) {
    this._title = title;
  }
  get title() {
    return this._title;
  }

}

然后在组件中导入服务和getset变量:

Then in your component import the service and get or set the variable:

import { AdminComponent } from 'admin/admin.component';
import { Component, ViewChild, AfterViewChecked } from '@angular/core';
import { HeaderService } from 'path/to/your/service';

@Component({
    selector: 'monitor-header',
    templateUrl: './header.monitor.component.html',
    styleUrls: ['./header.monitor.component.css']
})

export class HeaderMonitorComponent implements AfterViewChecked {

    @ViewChild(AdminComponent) private admin: AdminComponent;

    private monitorTitle: string;

    constructor(private headerService: HeaderService) {} // Import service here


    ngAfterViewChecked() {
        this.monitorTitle = this.headerService.title;
    }
 }

您只需要确保使用this.headerService.title = 'yourTitle';

我只是不确定哪个组件首先被加载.

I am just not sure which component gets loaded first.

您应该在此处查看Angular Services: https://angular.io/tutorial/toh-pt4

You should check out Angular Services here: https://angular.io/tutorial/toh-pt4

也可以在此处查看Angular组件交互: https://angular.io/guide/component-interaction

Also check out Angular Component Interaction here: https://angular.io/guide/component-interaction

编辑#2:

这是在您的服务中订阅该标题的另一种方法:

Here is another way to subscribe to that title in your Service:

所以下面在这里我创建了一个Subject类型为string的方法,在这里告诉它的方法是下一个要保存和发送的字符串.

So here below I have created a Subject that is of type string, and a method that tells it here is the next string to hold and send.

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

@Injectable()
export class HeaderService {

  public titleSubject: Subject<string> = new Subject<string>();

  constructor() { }

  setNextTitle(title) {
    this.titleSubject.next();
  }

}

然后在您的HeaderMonitorComponent中,您想像这样订阅Subject:

Then in your HeaderMonitorComponent you would want to subscribe to that Subject like so:

import { AdminComponent } from 'admin/admin.component';
import { Component, OnInit ViewChild, AfterViewChecked } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HeaderService } from 'path/to/your/service';

@Component({
    selector: 'monitor-header',
    templateUrl: './header.monitor.component.html',
    styleUrls: ['./header.monitor.component.css']
})

export class HeaderMonitorComponent implements OnInit, AfterViewChecked {

    @ViewChild(AdminComponent) private admin: AdminComponent;

    private monitorTitle: string;
    titleObservable: Observable<string>;

    constructor(private headerService: HeaderService) {} // Import service here

    ngOnInit() {

       this.titleObservable = this.headerService.titleSubject.asObservable();
       this.titleObservable.subscribe((title) => {
          this.monitorTitle = title;
       });
    }

    ngAfterViewChecked() {
        this.monitorTitle = this.headerService.title;
    }
 }

然后在您的AdminComponent中,只要单击该按钮,就调用this.headerService.setNextTitle(title),然后您在HeaderMonitorComponent中预订的新标题将得到确认,并替换monitorTitle的当前值.

Then in your AdminComponent, whenever the button is clicked, call this.headerService.setNextTitle(title) and the new title which you are subscribing to in the HeaderMonitorComponent will then be acknowledged and replace the current value of monitorTitle.

这是处理数据传递的另一种快速方法.

Just another quick way to handle the data passing through.

这篇关于角2 @ViewChild不起作用.无法读取媒体资源的“标题"的未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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