Búsqueda de sitios web

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.