asincrónico - cómo esperar a que se renderice el componente hasta que se recopilen todos los datos en Angular 2
Intenté muchas cosas para que ngModel funcionara en mi página de edición, pero me da un error. El error ocurre porque ngModel intenta obtener los datos antes de que se carguen. Mira mi código a continuación.
ComponenteEdicionProducto
import 'rxjs/add/operator/switchMap';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { Location } from '@angular/common';
import { Product } from './../shared/product.model';
import { ProductService } from './../shared/product.service';
@Component({
selector: 'product-edit',
template: require('./product-edit.component.html'),
providers: [ProductService]
})
export class ProductEditComponent implements OnInit {
product: Product;
name2: boolean = false;
constructor(
private productService: ProductService,
private route: ActivatedRoute,
private location: Location,
private router: Router
) { }
ngOnInit(): void {
var test = this.route.params
.switchMap((params: Params) => this.productService.getProduct(+params['id']))
.subscribe(product => this.product = product).closed;
console.log(test);
if (test['closed']) {
this.name2 = true;
}
}
goBack(): void {
this.location.back();
}
onSave(): void {
this.router.navigate(['product-edit', this.product]);
}
}
ProducirEditar HTML
<div class="product-edit">
<h2>Edit: {{product?.name}}</h2>
<div class="form-group row" *ngIf="name2">
<label for="name" class="col-2 col-form-label">Name</label>
<div class="col-10">
<input class="form-control" id="name" [(ngModel)]="name2" placeholder="" />
</div>
</div>
</div>
¿Cómo puedo esperar hasta que los datos se carguen y luego renderizar mi componente?
Respuesta #1
También puedes usar el enrutador para precargar los datos del producto para ti antes de que incluso se instancie el ProductEditComponent.
Más específicamente, necesitas usar un guardia Resolve en la declaración de la ruta, por ejemplo:
{
path: 'product/:productId',
component: ProductEditComponent,
resolve: { product: ProductResolver }
}
donde ProductResolver es un servicio personalizado que cargará el producto con el id productId.
Consulta la documentación oficial, que contiene un ejemplo completo que muestra cómo declarar la ruta, cómo implementar el resolve y cómo recuperar los datos preobtenidos dentro de un componente: https://angular.io/docs/ts/latest/guide/router.html#resolve-guard
Respuesta #2
Solo puedo asumir que está relacionado con que el objeto producto no esté instanciado. Usa *ngIf así. No hay necesidad de inicializarlo en null ya que null es 'falsy'
<div class="product-edit" *ngIf="product">
<h2>Edit: {{product?.name}}</h2>
<div class="form-group row" *ngIf="name2">
<label for="name" class="col-2 col-form-label">Name</label>
<div class="col-10">
<input class="form-control" id="name" [(ngModel)]="name2" placeholder="" />
</div>
</div>
