也许有人可以通过模态对话帮助我创建一个CRUD。我已经设法添加,删除,但我需要编辑。话虽如此,我已经设法以各自的方式捕获每条记录的数据,但我无法保存更改,我收到以下错误:Error: Function DocumentReference.update() called with invalid data. Unsupported field value: undefined (found in field titulo)
。我和Firestore合作。
阙-hacemos-admin.component.ts
import { Component, OnInit, Inject } from '@angular/core';
//Firestore
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
//Modal Material Design
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { AgregarComponent } from '../agregar/agregar.component';
import { EditarComponent } from '../editar/editar.component';
import { EliminarComponent } from '../eliminar/eliminar.component';
import { Title } from '@angular/platform-browser/src/browser/title';
export interface Servicios { titulo?: string; descripcion?: string };
export interface ServiciosId extends Servicios { id: string; };
@Component({
selector: 'app-que-hacemos-admin',
templateUrl: './que-hacemos-admin.component.html',
styleUrls: ['./que-hacemos-admin.component.scss']
})
export class QueHacemosAdminComponent implements OnInit {
titulo: string;
descripcion: string;
servicio: Servicios;
serviciosCollection: AngularFirestoreCollection<Servicios>;
serviciosObservable: Observable<Servicios[]>;
// dialogRef: MatDialogRef<EditarComponent>;
DocPredicate: any;
constructor(private afs: AngularFirestore, public dialog: MatDialog) { }
ngOnInit() {
this.getQueHacemos();
}
getQueHacemos() {
this.serviciosCollection = this.afs.collection('servicios', ref => ref.orderBy('titulo'));
this.serviciosObservable = this.serviciosCollection.snapshotChanges().map(arr => {
return arr.map(snap => {
const data = snap.payload.doc.data() as Servicios;
const id = snap.payload.doc.id;
return { id, ...data };
});
});
};
agregarModal() {
let dialogRef = this.dialog.open(AgregarComponent, {
width: '550px'
} );
};
editarModal(servicio) {
let dialogRef = this.dialog.open(EditarComponent, {
width: '550px',
data: {
titulo: servicio ? servicio.titulo :'',
descripcion: servicio ? servicio.descripcion : '',
}
} );
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.serviciosCollection.doc(servicio.id).update({
titulo: this.titulo,
descripcion: this.descripcion,
});
}
})
};
eliminarModal(servicio) {
let dialogRef = this.dialog.open(EliminarComponent, {
} );
dialogRef.afterClosed().subscribe(estado => {
if (estado) {
this.serviciosCollection.doc(servicio.id).delete();
}
})
};
}
&#13;
阙-hacemos-admin.component.html
<div class="my-5 d-flex justify-content-between">
<div><h2>¿Qué hacemos? - Admin</h2></div>
<div><button class="btn btn-primary" (click)="agregarModal()">Agregar servicio</button></div>
</div>
<table class="table mb-5">
<thead>
<tr>
<th scope="col">Servicio</th>
<th scope="col">Descripción</th>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let servicio of serviciosObservable | async">
<td class="text-primary">{{ servicio.titulo }}</td>
<td>{{ servicio.descripcion }}</td>
<td><button class="btn btn-outline-secondary btn-sm" (click)="editarModal(servicio)">Editar</button></td>
<td><button class="btn btn-outline-danger btn-sm" (click)="eliminarModal(servicio)">Eliminar</button></td>
</tr>
</tbody>
</table>
&#13;
editar.component.ts
import { Component, OnInit, Inject } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
//Firestore
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
//Modal Material Design
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
export interface Servicios { titulo: string; descripcion: string }
export interface ServiciosId extends Servicios { id: string; }
@Component({
selector: 'app-editar',
templateUrl: './editar.component.html',
styleUrls: ['./editar.component.scss']
})
export class EditarComponent implements OnInit {
titulo: string;
descripcion: string;
form: FormGroup;
servicio: string;
serviciosCollection: AngularFirestoreCollection<Servicios>;
serviciosObservable: Observable<Servicios[]>;
constructor(
private afs: AngularFirestore,
public dialog: MatDialog,
public dialogRef: MatDialogRef<EditarComponent>,
@Inject(MAT_DIALOG_DATA) public data,
private formBuilder: FormBuilder
) { }
ngOnInit() {
this.getQueHacemos();
this.form = this.formBuilder.group({
titulo: this.data ? this.data.titulo : '',
descripcion: this.data ? this.data.descripcion : ''
})
}
getQueHacemos() {
this.serviciosCollection = this.afs.collection('servicios', ref => ref.orderBy('titulo'));
this.serviciosObservable = this.serviciosCollection.snapshotChanges().map(arr => {
return arr.map(snap => {
const data = snap.payload.doc.data() as Servicios;
const id = snap.payload.doc.id;
return { id, ...data };
});
});
}
editar() {
this.dialogRef.close(true)
}
cancelar(){
this.dialogRef.close(false)
}
}
&#13;
editar.component.html
<form action="" [formGroup]="form">
<div class="m-2">
<div class="text-center">
<h4 class="mb-4">Editar Servicio</h4>
</div>
<div class="form-group">
<label>Título del servicio</label>
<input type="text" class="form-control" placeholder="Título servicio" formControlName="titulo">
</div>
<div class="form-group">
<label>Descripción del servicio</label>
<textarea class="form-control" rows="8" placeholder="Descripción" formControlName="descripcion"></textarea>
</div>
<div class="text-right mt-3">
<button class="btn btn-light" (click)="cancelar()">Cancelar</button>
<button type="submit" class="btn btn-primary" (click)="editar()">Guardar cambios</button>
</div>
</div>
</form>
&#13;
答案 0 :(得分:2)
调用服务时,que-hacemos-admin.component.ts中this.titulo的值未定义,因为您从未设置此变量的值。 Firestore不接受未定义的值。 Null会好的。
首先,你应该在editar.component.ts中返回对话框值,而不仅仅是true。
editar() {
this.dialogRef.close(this.form.value)
}
在处理对话框结果时,必须在que-hacemos-admin.component.ts中使用这些值。变量result包含上面在对话框中返回的值。
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.serviciosCollection.doc(servicio.id).update({
titulo: result.titulo,
descripcion: result.descripcion,
});
}
})