Tengo un problema al pasar datos asíncronos al componente secundario. Estoy tratando de escribir un generador de formularios dinámicos. El problema comienza cuando intento llamar a json a través de Observable y pasarlo al componente secundario.

Servicio:

generateSearchFields2(): Observable<any> {
        return this.http
            .get(this.API + 'searchFields')
            .map((res:Response) => {
                res.json().data as any;
                for (var i = 0; i < res.json().data.length; i++) {
                    var searchField = res.json().data[i];
                    switch (searchField.component) {
                        case "TextboxQuestion": 

                            let TXQ: TextboxQuestion = new TextboxQuestion({
                                key: searchField.key,
                                label: searchField.label,
                                value: searchField.value,
                                required: searchField.required,
                                order: searchField.order
                            });
                            this.searchFieldModels.push(TXQ);
                            console.log("TXQ: ", TXQ, this.searchFieldModels);
                            break;
                        case "DropdownQuestion": 

                            let DDQ: DropdownQuestion = new DropdownQuestion({
                                key: searchField.key,
                                label: searchField.label,
                                required: searchField.required,
                                options: searchField.options,
                                order: searchField.order
                            });
                            this.searchFieldModels.push(DDQ);
                            console.log("TXQ: ", DDQ, this.searchFieldModels);
                            break;
                        default:
                            alert("DEFAULT");
                            break;
                    }
                }
                return this.searchFieldModels.sort((a, b) => a.order - b.order);
            })
            .catch(this.handleError);
    }

Padre del componente:

generateSearchFields2() {
    this.service.generateSearchFields2()
      .subscribe(res => this.searchFields = res)
  }

Estoy pasando la variable a través de la directiva INPUT en la plantilla principal a la secundaria: [searchFields]="searchFields"

El problema está en el componente hijo, donde searchField tiene un valor indefinido. En este niño, paso valor a otro servicio, para crear formContros, pero también obtuve indefinido allí. Los datos que faltan comienzan aquí, en niño:

@Input() searchFields: SearchBase<any>[] = [];

ngOnInit() {   
    this.form = this.qcs.toFormGroup(this.searchFields);
    console.log("ONINIT DYNAMIC FORM COMPONENT: ", this.searchFields);

  }

Por favor, para obtener una pista sobre cómo puedo pasar la variable asíncrona, para no perder datos mientras tanto

4
Uland Nimblehoof 17 ene. 2017 a las 11:27

2 respuestas

Puedes convertir a @Input() searchFields en un setter

private _searchFields: SearchBase<any>[] = [];
@Input() set searchFields(value SearchBase<any>[]) {
  if(value != null) {
    this.form = this.qcs.toFormGroup(this.searchFields);
    console.log("ONINIT DYNAMIC FORM COMPONENT: ", this.searchFields);
  }
}

get searchFields() : SearchBase<any>[] {
  return this.searchFields;
}

También puede utilizar ngOnChanges () que es se llama cada vez que se actualiza una entrada, pero un establecedor suele ser más conveniente, excepto quizás cuando el código ejecutado depende de que se establezcan múltiples entradas.

6
Günter Zöchbauer 17 ene. 2017 a las 11:31
1
¿Puede explicar más sobre la diferencia entre setter y ngOnChanges ()?
 – 
YD_
1 ago. 2017 a las 10:00

En el evento ngOnInit, el data que proviene del parent aún no está vinculado. Entonces tu searchFields es undefined todavía. Puede usarlo en el evento del ciclo de vida del componente NgAfterViewInit.

@Input() searchFields: SearchBase<any>[] = [];

ngAfterViewInit() {   
    this.form = this.qcs.toFormGroup(this.searchFields);
    console.log("ONINIT DYNAMIC FORM COMPONENT: ", this.searchFields);
}

Para otros casos, puede ver eventos del ciclo de vida del componente Angular2

1
Suren Srapyan 17 ene. 2017 a las 11:28