angular - ng2-dragula y formulario dinámico sin sincronización directa
Tengo un formulario generado dinámicamente por el usuario:
// this._fb is a FormBuilder
ngOnInit():void {
this.myForm = this._fb.group({
message: this._fb.array([
])
});
el JSON generado es algo así
{
"message": [
{
"type": 1,
"value": "first message",
},
{
"type": 1,
"value": "second message",
}
]
}
He añadido la directiva ng2-dragula para cambiar el orden de los mensajes
<form [formGroup]="myForm">
<div formArrayName="message">
<div [dragula]='"bag-one"' [dragulaModel]='myForm.controls.message.controls'>
<div *ngFor="let c of myForm.controls.message.controls; let i=index" class="panel panel-default" >
<div class="panel-body" [formGroupName]="i">
<label>value</label>
<input type="text" class="form-control" formControlName="value">
</div>
</div>
</div>
</div>
La función de arrastre está funcionando bien, sin embargo, cuando estoy mostrando el JSON de mi formulario, todavía está en el orden antiguo, excepto si empiezo a cambiar el contenido de un campo. En ese caso, el formulario se actualiza.
Respuesta #1
Así que he encontrado una solución, no estoy seguro de que sea la mejor y soy bastante nuevo en Angular, pero al menos está funcionando.
Así que me di cuenta de que necesito encontrar una manera de emitir un evento desde el formulario.
En mi formulario tengo en realidad un valor "order" que corresponde al id en la lista, así que he hecho lo siguiente:
_dragulaService.dropModel.subscribe((value:any) => {
console.log(value);
this.onDropModel(value.slice(1));
});
}
private onDropModel(args:any):void {
for (let i = 0; i < (<FormArray>this.myForm.get('message')).length; ++i) {
(<FormArray>this.myForm.get('message')).at(i).patchValue("order", i);
}
}
Respuesta #2
Una solución limpia de Angular 16 aquí:
this.dragulaService.dropModel('placeholder-sections').subscribe((value:any) => {
const placeholderSections = this.getPlaceholderSections();
// Dragula provides the source and target index, and we can use these to just swap out the indexes in the actual FormArray
placeholderSections.removeAt(value.sourceIndex);
placeholderSections.insert(value.targetIndex, value.item);
});
getPlaceholderSections(): FormArray {
return this.promptEditor.get('placeholderSections') as FormArray;
}
y HTML:
<div formArrayName="placeholderSections" dragula="placeholder-sections" [(dragulaModel)]="this.getPlaceholderSections().controls">
<div *ngFor="let placeHolderSection of this.getPlaceholderSections().controls; let i = index" [formGroupName]=i>
...
</div>
</div>
También podrías agregar alguna llamada a la API del backend a la
this.dragulaService.dropModel('placeholder-sections').subscribe
sección, para guardar el pedido al mismo tiempo.
