Angular 2 @ViewChild 不工作。无法读取未定义的 属性 "title"
Angular 2 @ViewChild not working. Cannot Read Property "title" of Undefined
即使在使用@ViewChild 导入后,我也无法访问组件的属性。下面是代码。
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';
}
ERROR 错误:未捕获(承诺):TypeError:无法读取未定义的 属性 'title'
类型错误:无法读取未定义的 属性 'title'
帮我解决这个错误。
您应该检查 AfterViewChecked
中的 @ViewChild
而不是 AfterViewInit
。您也可以像这样捆绑 @angular/core
导入:
import { Component, ViewChild, AfterViewInit } from '@angular/core';
。然后,不要实施 AfterViewInit
,只需实施 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;
}
}
一个问题:这些都是 parent 组件还是其中一个组件是另一个组件的 child?我问的原因是您可能想研究在组件之间传递该变量的不同方法,因为这可以通过 @Input
或使用服务来存储和设置 header 变量来实现。我希望这能有所帮助。
编辑:
要回答您的评论,您应该创建这样的服务:
import { Injectable } from '@angular/core';
@Injectable()
export class HeaderService {
_title: string;
constructor() { }
set title(title) {
this._title = title;
}
get title() {
return this._title;
}
}
然后在您的组件中导入服务和 get
或 set
变量:
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';
在其中一个组件中设置标题
我只是不确定首先加载哪个组件。
您应该在此处查看 Angular 服务:https://angular.io/tutorial/toh-pt4
另请在此处查看 Angular 组件交互:https://angular.io/guide/component-interaction
编辑#2:
这是在您的服务中订阅该标题的另一种方式:
所以在下面我创建了一个 Subject
类型的字符串,一个方法告诉它这里是要保存和发送的下一个字符串。
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
:
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 中订阅的新标题将被确认并替换 [= 的当前值31=]。
另一种快速处理数据传递的方法。
即使在使用@ViewChild 导入后,我也无法访问组件的属性。下面是代码。
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';
}
ERROR 错误:未捕获(承诺):TypeError:无法读取未定义的 属性 'title' 类型错误:无法读取未定义的 属性 'title'
帮我解决这个错误。
您应该检查 AfterViewChecked
中的 @ViewChild
而不是 AfterViewInit
。您也可以像这样捆绑 @angular/core
导入:
import { Component, ViewChild, AfterViewInit } from '@angular/core';
。然后,不要实施 AfterViewInit
,只需实施 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;
}
}
一个问题:这些都是 parent 组件还是其中一个组件是另一个组件的 child?我问的原因是您可能想研究在组件之间传递该变量的不同方法,因为这可以通过 @Input
或使用服务来存储和设置 header 变量来实现。我希望这能有所帮助。
编辑:
要回答您的评论,您应该创建这样的服务:
import { Injectable } from '@angular/core';
@Injectable()
export class HeaderService {
_title: string;
constructor() { }
set title(title) {
this._title = title;
}
get title() {
return this._title;
}
}
然后在您的组件中导入服务和 get
或 set
变量:
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';
我只是不确定首先加载哪个组件。
您应该在此处查看 Angular 服务:https://angular.io/tutorial/toh-pt4
另请在此处查看 Angular 组件交互:https://angular.io/guide/component-interaction
编辑#2:
这是在您的服务中订阅该标题的另一种方式:
所以在下面我创建了一个 Subject
类型的字符串,一个方法告诉它这里是要保存和发送的下一个字符串。
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
:
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 中订阅的新标题将被确认并替换 [= 的当前值31=]。
另一种快速处理数据传递的方法。