![](/img/trans.png)
[英]Cannot read property of undefined @ViewChild not working Angular 5
[英]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';
}
錯誤錯誤:未捕獲(承諾):TypeError:無法讀取未定義的屬性“ title” TypeError:無法讀取未定義的屬性“ title”
幫助我解決此錯誤。
您應該在@ViewChild
中檢查AfterViewChecked
而不是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;
}
}
一個問題:這兩個都是父組件,還是其中一個組件是另一個組件的子組件? 我問的原因是,您可能想研究在組件之間傳遞該變量的另一種方法,因為這可以通過@Input
或使用服務來存儲和設置標頭變量來實現。 我希望這可以有所幫助。
編輯:
要回答您的評論,您應該創建這樣的服務:
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';
在其中一個組件中設置標題this.headerService.title = 'yourTitle';
我只是不確定哪個組件首先被加載。
您應該在這里查看Angular Services: https : //angular.io/tutorial/toh-pt4
也可以在這里查看Angular Component Interaction: 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中預訂的新標題,並替換monitorTitle
的當前值。
這是處理數據傳遞的另一種快速方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.