web-dev-qa-db-ja.com

観察可能な値を@Input()に渡す方法Angular 4

angularが初めてで、サービスgetAnswers():Observable<AnswerBase<any>[]>と相互に関連する2つのコンポーネントがあるという次の状況があります。

  • オンライン引用符
  • 動的形式

online-quoteコンポーネントはそのgetAnswers():Observable<AnswerBase<any>[]>メソッドでサービスngOnInit()を呼び出し、この結果はコンポーネントに渡されますdynamic-form

状況を説明するために、これは私の2つのコンポーネントのコードです。

online-quote.component.html:

_ <div>
    <app-dynamic-form [answers]="(answers$ | async)"></app-dynamic-form>
</div>
_

online-quote.component.ts:

_@Component({
  selector: 'app-online-quote',
  templateUrl: './online-quote.component.html',
  styleUrls: ['./online-quote.component.css'],
  providers:  [DynamicFormService]
})
export class OnlineQuoteComponent implements OnInit {

  public answers$: Observable<any[]>;

  constructor(private service: DynamicFormService) {

   }

  ngOnInit() {
    this.answers$=this.service.getAnswers("CAR00PR");
  }

}
_

dynamic-form.component.html:

_<div *ngFor="let answer of answers">
 <app-question *ngIf="actualPage===1" [answer]="answer"></app-question>
</div>
_

dynamic-form.component.ts:

_@Component({
  selector: 'app-dynamic-form',
  templateUrl: './dynamic-form.component.html',
  styleUrls: ['./dynamic-form.component.css'],
  providers: [ AnswerControlService ]
})
export class DynamicFormComponent implements OnInit {
  @Input() answers: AnswerBase<any>[];

  constructor(private qcs: AnswerControlService, private service: DynamicFormService) {  }

  ngOnInit() {

    this.form = this.qcs.toFormGroup(this.answers);

  }
_

私の質問は、サービスの結果情報getAnswers():Observable<AnswerBase<any>[]>online-quoteからdynamic-formに情報を渡す正しい方法は何か観察可能。

いろいろ試してみましたが、うまくいきません。誰かに助けてもらいたいです。どうもありがとうございました!

14
AlejoDev

DynamicFormService.getAnswers('CAR00PR')asynchronous(おそらくそうです)と仮定し、_async Pipe_を使用して非同期の結果を渡すことは正しい方法ですが、非同期を取得することは期待できませんAsynchonousのため、DynamicFormComponentが作成されたときの結果( at ngOnInit )。以下のコード行を実行すると、結果はまだ準備ができていません。

_this.form = this.qcs.toFormGroup(this.answers);
_

問題を解決する方法はいくつかあります。

1. ngOnChangesライフフックで@Input() answersのvalueChangeをリッスンします。

_ngOnChanges(changes) {
  if (changes.answers) {
    // deal with asynchronous Observable result
    this.form = this.qcs.toFormGroup(changes.answers.currentValue);
  }
}
_

2. ObservableをDynamicFormComponentに直接渡し、サブスクライブして結果をリッスンします。

online-quote.component.html:

_<app-dynamic-form [answers]="answers$"></app-dynamic-form>
_

dynamic-form.component.ts:

_@Component({
  ...
})
export class DynamicFormComponent implements OnInit {
  @Input() answers: Observable<AnswerBase[]>;

  ngOnInit() {
    this.answers.subscribe(val => {
      // deal with asynchronous Observable result
      this.form = this.qcs.toFormGroup(this.answers);
    })
}
_
21
Pengyy

私はOPとほぼ同じユースケースを持っていて、提案されたソリューションも私のために働きました。

簡単にするために、私は自分のケースで機能する別のソリューションを見つけましたが、もう少しシンプルに見えます。テンプレートで以前に* ngIf構造ディレクティブの一部として非同期パイプを適用し、変数を使用して、既に評価された値を子コンポーネントにパススルーできるようにしました。

<div *ngIf="answers$ | async as answers">
    <app-dynamic-form [answers]="answers"></app-dynamic-form>
</div>
1

online-quote.component.tsを次のように変更します。

    @Component({
  selector: 'app-online-quote',
   templateUrl: './online-quote.component.html',
  styleUrls: ['./online-quote.component.css'],
  providers:  [DynamicFormService]
})
export class OnlineQuoteComponent implements OnInit {

  public answers$: AnswerBase<any>[];

  constructor(private service: DynamicFormService) {

   }

  ngOnInit() {
    this.service.getAnswers("CAR00PR").subscribe(success=>{this.answers$=success;});
  }

}
0
Praveen Kumar