web-dev-qa-db-fra.com

Comment passer une valeur observable à @Input () Angular 4

Je suis nouveau sur angular et j’ai la situation suivante, c’est-à-dire que j’ai un service getAnswers():Observable<AnswerBase<any>[]> et deux composants liés entre eux.

  • devis en ligne
  • forme-dynamique

online-quote composant appelle le service getAnswers():Observable<AnswerBase<any>[]> dans sa méthode ngOnInit() et le résultat de cette opération est transmis au composant formulaire dynamique.

Pour illustrer la situation, voici le code de mes deux composants:

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);

  }

Ma question est quelle est la bonne façon de transmettre les informations de devis en ligne à formulaire dynamique si les informations de résultat du service getAnswers():Observable<AnswerBase<any>[]> est un observable.

Je l'ai essayé à bien des égards mais ça ne marche pas. J'aimerais que quelqu'un m'aide avec ça. Merci beaucoup!

14
AlejoDev

Supposons que DynamicFormService.getAnswers('CAR00PR') soit asynchrone (probablement), utiliser async Pipe Pour transmettre le résultat asynchrone est dans le bon sens, mais vous ne pouvez pas espérer obtenir le résultat asynchrone correctement. maintenant quand DynamicFormComponent est créé ( sur ngOnInit ) à cause de asynchrone. Le résultat n'est pas encore prêt lors de l'exécution de votre ligne de code ci-dessous.

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

Il existe plusieurs manières de résoudre votre problème.

1. écoutez valueChange of @Input() answers at ngOnChanges lifehook.

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

2. passez Observable directement dans DynamicFormComponent et abonnez-vous pour écouter le résultat.

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

J'avais un cas d'utilisation presque identique à OP et la solution proposée a également fonctionné pour moi.

Par souci de simplicité, j'ai imaginé une solution différente qui a fonctionné dans mon cas et semble un peu plus simple. J'ai appliqué le tube asynchrone plus tôt dans le modèle dans le cadre de la directive structurelle * ngIf et ai utilisé des variables pour pouvoir transmettre la valeur déjà évaluée au composant enfant.

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

modifier le online-quote.component.ts: comme suit

    @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