web-dev-qa-db-ja.com

angular 4:別のコンポーネントからメソッドを呼び出す

2つの兄弟コンポーネントがあり、1つのコンポーネントでhttp要求を実行しています。特定の条件が発生した場合、別のコンポーネントで記述された別のhttp要求を作成する必要があります。したがって、最初のコンポーネント内でメソッドを呼び出すことができるはずです。

これが最初のコンポーネントです。

import { Component, OnInit, Inject } from '@angular/core';
import { Http } from '@angular/http';
import { SendCardComponent } from '../send-card/send-card.component';

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

export class InputFieldComponent implements OnInit {

value = '';
output = '';
@Inject(SendCardComponent) saro: SendCardComponent;

constructor(private http : Http) { }
onEnter(value: string) { 

this.value = value;


this.http.post('http://localhost:5000/APIconversation/', {"val":value})
  .map(response=>response.json())
  .subscribe(
      data => {

            this.output = data.result.fulfillment.speech,
            if(data.result.fulfillment.speech == 'test'){
                saro.sendCard('done', '1' );   
            }               

       });

 } 

次のようなInputFieldComponentからsendCardComponentで定義されているsendCard()を呼び出そうとしています。

import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';

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

export class SendCardComponent implements OnInit {

constructor(private http : Http) { }

ngOnInit() {

}

 output = '';

 sendCard(value:string, id:number){
   this.http.post('http://localhost:5000/APIconversation/', {"val":value})
  .map(response=>response.json())
  .subscribe(
      data => {

             this.output = data.result.fulfillment.messages[1].payload.options[id].type = $('#'+(id+1)+'>span').html();  

      });
} //sendCard

}

Saro.sendCardを呼び出すとエラーが発生します。

[ts]名前 'saro'が見つかりません

何が間違っていますか?

6
Sivvio

InputFieldComponentにSendCardComponentのインスタンスを作成します

import { Http } from '@angular/http';
import { SendCardComponent } from '../send-card/send-card.component';

export class InputFieldComponent{

    //your other variables and methods

    constructor(private http : Http) { }

    let saro = new SendCardComponent(this.http);

    saro.sendCard()

}
14
Rahul Singh

対処すべき2つの問題があります。

1つ目は、依存性注入を使用する場合、コンポーネントに親子関係が必要であるということです。したがって、あなたの場合、InputFieldComponentSendCardComponentの子である場合、単純な(コンストラクター)依存性注入を使用して、SendCardComponentから親InputFieldComponentのインスタンスを取得できます。 _。

そして、2番目の問題である実装について説明します。上記を実行したい場合は、次のようになります。

export class InputFieldComponent implements OnInit {

  value = '';
  output = '';

  constructor(private http : Http, private saro: SendCardComponent) { }

  onEnter(value: string) { 

    this.value = value;
    this.saro.methodOnSendCardComponent();  
    ......

他の関係が存在する場合-InputFieldComponentSendCardComponentの親である場合、@ViewChildSendCardComponentのインスタンスをInputFieldComponentから取得します。

ただし、前述のとおり、上記の両方の方法では、ビュー階層を変更する必要があります。 2つのコンポーネントが兄弟としてとどまる必要がある場合、上記のどちらも機能しません。

さらに考えてみると、SendCardComponentへのアクセスだけでロジック(つまりメソッド)を使用する必要がある場合、そのロジックをサービスに抽象化して、階層内のどこでもそのサービスを使用できます。これは現在の問題を非常にきちんと回避し、一般的に適切なアドバイスです。正直なところ、コンポーネントは、動作をより高いレベルの懸念に集中させ、とにかくサービスに合理的にできる限り「アウトソース」する必要があります。

2
snorkpete