Binding Arrays

This article explains working with arrays when building TypeScript form views using client-side form binding.

Let us consider a form for the Java bean of this structure:

/**
 * Example bean with array field
 */
public class Group {
    ...

    public Person[] getPeople() {
        ...
    }

    public void setPeople(Person[] people) {
        ...
    }
}

Repeating the Array Item Template

A common need behind working with arrays is to iterate the items and stamp a template for every item.

With client-side form binding, the array models are iterable. You can iterate the array model directly, there is no need to get the value of the array.

When iterating an array model, you receive a binder node for the child item, which provides both the item model and value inside the loop respectively.

It is suggested to use a repeat directive for looping through the items and stamping the item templates.

import { html, LitElement } from 'lit';
import { customElement } from 'lit/decorators.js';

import { repeat } from 'lit/directives/repeat.js';

import { Binder, field } from '@vaadin/form';

import GroupModel from '.../GroupModel';

@customElement('group-form-view')
class GroupFormView extends LitElement {
  binder = new Binder(this, GroupModel);

  render() {
    return html`
      ${repeat(this.binder.model.people, personBinder => html`
        <div>
          <vaadin-text-field
           label="Full name"
           ...="${field(personBinder.model.fullName)}"
           ></vaadin-text-field>

          <strong>Full name:</strong>
          ${personBinder.value.fullName}
        </div>
      `)}
    `;
  }
}

Adding and Removing Array Items

To append or prepend a new item into an array, use the appendItem() method on the array binder node:

this.binder.for(this.binder.model.people).appendItem();
this.binder.for(this.binder.model.people).prependItem();

By default, the new item values are empty. You can optionally specify the new item value as an argument:

this.binder.for(this.binder.model.people).appendItem({fullName: 'Jane Doe'});

To remove an item, use the removeSelf() method on the item binder node:

personBinder.removeSelf();

The example below demonstrates adding and removing array items with the form view template:

class GroupFormView extends LitElement {
  // ...

  render() {
    return html`
      ${repeat(this.binder.model.people, personBinder => html`
        <div>
          <vaadin-text-field
           label="Full name"
           ...="${field(personBinder.model.fullName)}"
           ></vaadin-text-field>

          <vaadin-button
           @click="${() => personBinder.removeSelf()}
           >Delete</vaadin-button>
        </div>
      `)}

      <vaadin-button
       @click="${() => this.binder.for(this.binder.model.people).appendItem()}"
       >Add</vaadin-button>
    `;
  }
}