簡體   English   中英

角2 @ViewChild不起作用。 無法讀取未定義的屬性“標題”

[英]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;
  }

}

然后在您的組件中導入服務並getset變量:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM