Angular 将数据从服务传递到组件-->;子组件
简而言之,我用的是这个 我有一个场景,我必须通过从服务读取元素数据来动态创建控件。因此,当我从服务读取数据时,它是异步的,但我必须根据从服务接收到的数据创建一些具体的对象,并将其传递给子组件。这就是我的逻辑 主要组件的Html如下所示Angular 将数据从服务传递到组件-->;子组件,angular,firebase,rxjs,angular-services,angular4-forms,Angular,Firebase,Rxjs,Angular Services,Angular4 Forms,简而言之,我用的是这个 我有一个场景,我必须通过从服务读取元素数据来动态创建控件。因此,当我从服务读取数据时,它是异步的,但我必须根据从服务接收到的数据创建一些具体的对象,并将其传递给子组件。这就是我的逻辑 主要组件的Html如下所示 <ion-content padding class="container" *ngIf="questions"> <app-dynamic-form [questions]="questions"></app-dyn
<ion-content padding class="container" *ngIf="questions">
<app-dynamic-form [questions]="questions"></app-dynamic-form>
</ion-content>
主要组件的类别如下所示
Class ComponentMain{
@Input() questions: QuestionBase<any>[]=[];
constructor(public navCtrl: NavController, public navParams: NavParams,private qcs: Service)
{
qcs.getQuestions(this.parameter1.$key).subscribe(result => this.questions = result);
}
}
Class ComponentMain{
@输入()问题:问题库[]=[];
构造函数(公共navCtrl:NavController、公共navParams:navParams、私有qcs:Service)
{
qcs.getQuestions(this.parameter1.$key).subscribe(result=>this.questions=result);
}
}
子组件Html如下所示
<div *ngIf="form">
<form (ngSubmit)="onSubmit()" [formGroup]="form">
<div *ngFor="let question of questions" class="form-row">
<div *ngIf="question">
<app-question [question]="question" [form]="form"></app-question>
</div>
</div>
</form>
</div>
子组件如下所示
Class ChildComponent implements AfterViewInit {
@Input() questions: QuestionBase<any>[] = [];
Constructor(){
}
ngAfterViewInit(){
this.form = this.qcs.toFormGroup(this.questions);
}
}
Class ChildComponent实现AfterViewInit{
@输入()问题:问题库[]=[];
构造函数(){
}
ngAfterViewInit(){
this.form=this.qcs.toFormGroup(this.questions);
}
}
第二个子组件依赖于childComponent来创建控件。因此,控件仅在第二个子组件的ngOnit中填充,因此不会创建控件。我试着使用很多生命周期挂钩,比如OnInit、OnChanges等,但没有一个真正给了我结果。我确信我错过了一些我无法理解的东西
Class Service(){
questions: QuestionsData<any>[]=[];
getQuestions(FormKey: string) {
var dbQuestions = this.af.list('/elements', {
query: {
limitToLast: 200,
orderByChild: 'formid',
equalTo: FormKey
}
})
dbQuestions.subscribe(snapshots=>{
snapshots.forEach(elementData => {
this.questions.push(new TextboxQuestion({
key: elementData.elementname,
label: elementData.displaytext,
value: elementData.elementvalue,
required: false,
order: elementData.sortorder
}))
}
}
}
Class服务(){
问题:问题数据[]=[];
getQuestions(FormKey:string){
var dbQuestions=this.af.list(“/elements”{
查询:{
限时:200,
orderByChild:“formid”,
等号:FormKey
}
})
dbQuestions.subscribe(快照=>{
snapshots.forEach(elementData=>{
this.questions.push(新文本框问题({
键:elementData.elementname,
标签:elementData.displaytext,
值:elementData.elementvalue,
必填项:false,
订单:elementData.sortorder
}))
}
}
}
我不确定是否理解您的问题,但当我需要将数据从服务传递到组件时,我会以这种方式使用subscription
两个组件(父组件及其子组件或其他不同组件)可以共享其接口支持双向通信的服务
与观察者模式类似,在本例中,服务实例的范围是来自组件(发布者)和其他组件(订阅者)的通知
mycomponent.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MyComponentService{
// Observable
private sampleObservable = new Subject<boolean>();
// Observable boolean streams
sampleSubscriber = this.sampleObservable.asObservable();
// Event for notification from publisher to subscriber
sampleEventChanged(value:boolean)
{
this.sampleObservable.next();
}
}
import { Component } from '@angular/core';
import { MyService } from './mycomponent.service';
@Component({
selector: 'app-my-control-publisher',
template: `
<h2>This is the publisher control</h2>
<button (click)="announce()">Announce to subscriber</button>
`,
providers: [MyService]
})
export class MyControlPublisherComponent
{
constructor(private myService: MyService) { }
announce()
{
this.myService.sampleEventChanged(true);
}
}
import { Component, OnDestroy } from '@angular/core';
import { MyService } from './mycomponent.service';
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'app-my-control-subscriber',
template: `
<h2>This is the subscriber control</h2>
`,
})
export class MyControlSubscriberComponent
{
// Subscriptions
private componentSubscription: Subscription;
constructor(private myService: MyService)
{
// Subscription of the notifications
this.componentSubscription= this.myService.sampleSubscriber.subscribe(value =>
{
// Put the code for manage the notification here
}
}
ngOnDestroy()
{
// Release subscription to avoid memory leaks when the component is destroyed
this.componentSubscription.unsubscribe();
}
}
从'@angular/core'导入{Injectable};
从'rxjs/Subject'导入{Subject};
@可注射()
导出类MyComponentService{
//可见
private sampleObservable=新主题();
//可观察的布尔流
sampleSubscriber=this.sampleObservable.asObservable();
//从发布服务器通知订阅服务器的事件
sampleEventChanged(值:布尔值)
{
this.sampleObservable.next();
}
}
在要通知所有订阅者其状态更改的组件中:
mycomponent publisher.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MyComponentService{
// Observable
private sampleObservable = new Subject<boolean>();
// Observable boolean streams
sampleSubscriber = this.sampleObservable.asObservable();
// Event for notification from publisher to subscriber
sampleEventChanged(value:boolean)
{
this.sampleObservable.next();
}
}
import { Component } from '@angular/core';
import { MyService } from './mycomponent.service';
@Component({
selector: 'app-my-control-publisher',
template: `
<h2>This is the publisher control</h2>
<button (click)="announce()">Announce to subscriber</button>
`,
providers: [MyService]
})
export class MyControlPublisherComponent
{
constructor(private myService: MyService) { }
announce()
{
this.myService.sampleEventChanged(true);
}
}
import { Component, OnDestroy } from '@angular/core';
import { MyService } from './mycomponent.service';
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'app-my-control-subscriber',
template: `
<h2>This is the subscriber control</h2>
`,
})
export class MyControlSubscriberComponent
{
// Subscriptions
private componentSubscription: Subscription;
constructor(private myService: MyService)
{
// Subscription of the notifications
this.componentSubscription= this.myService.sampleSubscriber.subscribe(value =>
{
// Put the code for manage the notification here
}
}
ngOnDestroy()
{
// Release subscription to avoid memory leaks when the component is destroyed
this.componentSubscription.unsubscribe();
}
}
从'@angular/core'导入{Component};
从“/mycomponent.service”导入{MyService};
@组成部分({
选择器:“应用程序我的控件发布者”,
模板:`
这是发布者控件
向订户宣布
`,
提供者:[MyService]
})
导出类MyControlPublisherComponent
{
构造函数(私有myService:myService){}
宣布
{
this.myService.sampleEventChanged(true);
}
}
在订阅服务器组件中,要获取通知的用户
mycomponent订户.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MyComponentService{
// Observable
private sampleObservable = new Subject<boolean>();
// Observable boolean streams
sampleSubscriber = this.sampleObservable.asObservable();
// Event for notification from publisher to subscriber
sampleEventChanged(value:boolean)
{
this.sampleObservable.next();
}
}
import { Component } from '@angular/core';
import { MyService } from './mycomponent.service';
@Component({
selector: 'app-my-control-publisher',
template: `
<h2>This is the publisher control</h2>
<button (click)="announce()">Announce to subscriber</button>
`,
providers: [MyService]
})
export class MyControlPublisherComponent
{
constructor(private myService: MyService) { }
announce()
{
this.myService.sampleEventChanged(true);
}
}
import { Component, OnDestroy } from '@angular/core';
import { MyService } from './mycomponent.service';
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'app-my-control-subscriber',
template: `
<h2>This is the subscriber control</h2>
`,
})
export class MyControlSubscriberComponent
{
// Subscriptions
private componentSubscription: Subscription;
constructor(private myService: MyService)
{
// Subscription of the notifications
this.componentSubscription= this.myService.sampleSubscriber.subscribe(value =>
{
// Put the code for manage the notification here
}
}
ngOnDestroy()
{
// Release subscription to avoid memory leaks when the component is destroyed
this.componentSubscription.unsubscribe();
}
}
从'@angular/core'导入{Component,OnDestroy};
从“/mycomponent.service”导入{MyService};
从'rxjs/Subscription'导入{Subscription};
@组成部分({
选择器:“应用程序我的控制订阅服务器”,
模板:`
这是订户控件
`,
})
导出类MyControlSubscriberComponent
{
//订阅
私有组件订阅:订阅;
构造函数(私有myService:myService)
{
//订阅通知
this.componentSubscription=this.myService.sampleSubscriber.subscripte(值=>
{
//将用于管理通知的代码放在此处
}
}
恩贡德斯特罗()
{
//释放订阅以避免组件销毁时内存泄漏
this.componentSubscription.unsubscribe();
}
}
我希望这能对您有所帮助。看看这个示例,它本质上是在运行时从元数据构建表单
有几条评论指出示例还没有完成
@Injectable()
导出类查询服务{
//Todo:从问题元数据的远程源获取
//Todo:使异步
getQuestions(){
...
以下是我完成并清除错误消息所采取的步骤
问题.service.ts 将
getQuestions
更改为异步返回问题
Injectable()
导出类查询服务{
建造师(
专用http:http
) {}
getQuestions$(){
常量url=https://api.myjson.com/bins/d0srd';
返回此.http.get(url)
.map(response=>response.json())
.map(questionMetadata=>this.metadataToQuestions(questionMetadata))
.map(questions=>questions.sort((a,b)=>a.order-b.order))
}
私有元数据问题(问题元数据){
返回questionMetadata.questions.map(this.toQuestion)
}
私人问题(elementData){
//展开以获取其他控件类型
返回新的TextboxQuestion({
键:elementData.elementname,
标签:elementData.displaytext,
值:elementData.elementvalue,
必填项:false,
订单:elementData.sortorder
})
}
}
app.component.ts 已更改变量<代码>问题