2

@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' を読み取れません

このエラーの解決にご協力ください。

4

1 に答える 1

8

@ViewChildAfterViewChecked代わりに をチェックする必要があり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;
    }
 }

1 つの質問: これらは両方とも親コンポーネントですか、それともコンポーネントの 1 つが他のコンポーネントの子になりますか? @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;
    }
 }

を使用してコンポーネントの1つにタイトルを設定することを確認する必要がありますthis.headerService.title = 'yourTitle';

どのコンポーネントが最初にロードされるのかわかりません。

ここで Angular Services を確認してください: 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 でサブスクライブしている新しいタイトルが認識され、 の現在の値が置き換えられますmonitorTitle

通過するデータを処理するもう 1 つの簡単な方法です。

于 2017-11-29T19:31:38.530 に答える