Angular 如何将可观察值传递给@Input()4

Angular 如何将可观察值传递给@Input()4,angular,typescript,rxjs,angular2-observables,angular2-decorators,Angular,Typescript,Rxjs,Angular2 Observables,Angular2 Decorators,我是angular的新手,我有以下情况,即我有一个服务getAnswers():可观察的和两个相互关联的组件 在线报价 动态表单 在线报价组件在其ngOnInit()方法中调用服务getAnswers():可观察的,其结果将传递给组件动态表单 为了说明这种情况,这是我的两个组件的代码: 在线-quote.component.html: <div> <app-dynamic-form [answers]="(answers$ | async)"></ap

我是angular的新手,我有以下情况,即我有一个服务
getAnswers():可观察的
和两个相互关联的组件

  • 在线报价
  • 动态表单
在线报价组件在其
ngOnInit()
方法中调用服务
getAnswers():可观察的
,其结果将传递给组件动态表单

为了说明这种情况,这是我的两个组件的代码:

在线-quote.component.html:

 <div>
    <app-dynamic-form [answers]="(answers$ | async)"></app-dynamic-form>
</div>
<div *ngFor="let answer of answers">
 <app-question *ngIf="actualPage===1" [answer]="answer"></app-question>
</div>
<app-dynamic-form [answers]="answers$"></app-dynamic-form>
<app-dynamic-form [answers]="answers$ | async"></app-dynamic-form>

在线-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");
  }

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

  }
@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);
    })
}
@Component({
  ...
})
export class DynamicFormComponent implements OnInit {
  @ObservableInput() Input("answers") answers$: Observable<string[]>;

  ...
}
@组件({
选择器:'应用程序在线报价',
templateUrl:“./online quote.component.html”,
样式URL:['./online quote.component.css'],
提供者:[DynamicFormService]
})
导出类OnlineQuoteComponent实现OnInit{
公众答案:$:可见;
构造函数(专用服务:DynamicFormService){
}
恩戈尼尼特(){
this.answers$=this.service.getAnswers(“CAR00PR”);
}
}
dynamic-form.component.html:

 <div>
    <app-dynamic-form [answers]="(answers$ | async)"></app-dynamic-form>
</div>
<div *ngFor="let answer of answers">
 <app-question *ngIf="actualPage===1" [answer]="answer"></app-question>
</div>
<app-dynamic-form [answers]="answers$"></app-dynamic-form>
<app-dynamic-form [answers]="answers$ | async"></app-dynamic-form>

dynamic-form.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");
  }

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

  }
@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);
    })
}
@Component({
  ...
})
export class DynamicFormComponent implements OnInit {
  @ObservableInput() Input("answers") answers$: Observable<string[]>;

  ...
}
@组件({
选择器:“应用程序动态表单”,
templateUrl:'./dynamic form.component.html',
样式URL:['./dynamic form.component.css'],
提供者:[应答控制服务]
})
导出类DynamicFormComponent在NIT上实现{
@Input()答案:AnswerBase[];
构造函数(私有qcs:AnswerControlService,私有服务:DynamicFormService){}
恩戈尼尼特(){
this.form=this.qcs.toFormGroup(this.answers);
}
我的问题是,如果服务的结果信息
getAnswers():Observable
是可观察的,那么将信息从在线报价传递到动态表单的正确方法是什么


我尝试过很多方法,但都不起作用。我希望有人能帮助我。非常感谢!

假设
DynamicFormService.getAnswers('CAR00PR')
是异步的(可能是),使用
async Pipe
传递异步结果是正确的,但是在创建
DynamicFormComponent
时(在ngOnInit),由于Asynchonous,您不能期望立即获得异步结果。运行下面的代码行时,结果尚未准备好

this.form = this.qcs.toFormGroup(this.answers);
有几种方法可以解决您的问题

1.在
ngOnChanges
lifehook收听
@Input()答案的值更改。
2.将Observable直接传递到
DynamicFormComponent
中,并订阅它以收听其结果。 在线-quote.component.html:

 <div>
    <app-dynamic-form [answers]="(answers$ | async)"></app-dynamic-form>
</div>
<div *ngFor="let answer of answers">
 <app-question *ngIf="actualPage===1" [answer]="answer"></app-question>
</div>
<app-dynamic-form [answers]="answers$"></app-dynamic-form>
<app-dynamic-form [answers]="answers$ | async"></app-dynamic-form>

dynamic-form.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");
  }

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

  }
@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);
    })
}
@Component({
  ...
})
export class DynamicFormComponent implements OnInit {
  @ObservableInput() Input("answers") answers$: Observable<string[]>;

  ...
}
@组件({
...
})
导出类DynamicFormComponent在NIT上实现{
@输入()答案:可观察;
恩戈尼尼特(){
this.answers.subscribe(val=>{
//处理异步可观测结果
this.form=this.qcs.toFormGroup(this.answers);
})
}

我有一个与OP几乎相同的用例,建议的解决方案也对我有效

为了简单起见,我想出了一个不同的解决方案,这个解决方案在我的案例中起作用,而且似乎更简单一些。我在模板的前面应用了异步管道,作为*ngIf structural指令的一部分,并使用变量将已经计算的值传递给子组件

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

我也遇到了同样的问题,我创建了一个小型库,提供了
可观察输入
装饰器来帮助解决这个问题:。这种情况的示例代码是:

在线-quote.component.html:

 <div>
    <app-dynamic-form [answers]="(answers$ | async)"></app-dynamic-form>
</div>
<div *ngFor="let answer of answers">
 <app-question *ngIf="actualPage===1" [answer]="answer"></app-question>
</div>
<app-dynamic-form [answers]="answers$"></app-dynamic-form>
<app-dynamic-form [answers]="answers$ | async"></app-dynamic-form>

dynamic-form.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");
  }

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

  }
@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);
    })
}
@Component({
  ...
})
export class DynamicFormComponent implements OnInit {
  @ObservableInput() Input("answers") answers$: Observable<string[]>;

  ...
}
@组件({
...
})
导出类DynamicFormComponent在NIT上实现{
@ObservableInput()输入(“答案”)答案$:可观察;
...
}

我的方法和建议是使用BehaviorSubject进行以下操作 理由 这是来自文档:

主体的变体之一是行为主体,它具有 “当前值”的概念。它存储发送到的最新值 它的消费者,无论何时新的观察者订阅,它都会 立即从BehaviorSubject接收“当前值”

我假设OP声明的子组件总是需要最后一个发出的值,因此我觉得BehaviorSubject更适合这个

在线报价组件

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

  public answers$: BehaviorSubject<any>;

  constructor(private service: DynamicFormService) {
       this.answers$ = new BehaviorSubject<any>(null);

   }

  ngOnInit() {
    
    this.service.getAnswers("CAR00PR").subscribe(data => {
            this.answer$.next(data); // this makes sure that last stored value is always emitted;
         });
  }

}
@组件({
选择器:'应用程序在线报价',
templateUrl:“./online quote.component.html”,
样式URL:['./online quote.component.css'],
提供者:[DynamicFormService]
})
导出类OnlineQuoteComponent实现OnInit{
公共答案$:行为主体;
构造函数(专用服务:DynamicFormService){
this.answers$=新行为主体(null);
}
恩戈尼尼特(){
this.service.getAnswers(“CAR00PR”).subscribe(数据=>{
this.answer$.next(data);//这确保始终发出最后存储的值;
});
}
}
在html视图中

<app-dynamic-form [answers]="answer$.asObservable()"></app-dynamic-form>

//这使主体发出可见的光

现在您可以订阅子组件中的值。订阅答案的方式没有变化 动态表单.component.ts

@Component({
  ...
})
export class DynamicFormComponent implements OnInit {
  @Input() answers: Observable<any>;

  ngOnInit() {
    this.answers.subscribe(val => {
      // deal with asynchronous Observable result
      this.form = this.qcs.toFormGroup(this.answers);
    })
}
@组件({
...
})
导出类DynamicFormComponent在NIT上实现{
@输入()答案:可观察;
恩戈尼尼特(){
this.answers.subscribe(val=>{
//处理异步可观测结果
this.form=this.qcs.toFormGroup(this.answers);
})
}

看起来不错,但在应用程序动态表单中如何处理它?在应用程序动态表单中,它不再是可观察的,只是一个答案库[]。我相信OP不必更改其中的任何代码。如果他只是处理原始数据对象,他可能不需要做任何进一步的工作,使其成为可行的解决方案。但是,他正在获取答案数据并将其转换为表单组,因此