FieldBindings are great, but they do not always ensure what they should ensure, i.e. that the model properties and field values are always in sync.

Specifically:
  • calling clear() on the FormPanel clears the fields, but does not update the model
  • calling reset() on the FormPanel resets the fields, but does not update the model
  • calling setValue() on a Field changes the displayed field value, but does not update the model
I believe that once bindings are in place, you should be assured that your model always reflects changes made to the field, whether programatically or by interacting with the field. Currently only changes made by interacting with the field are reflected into the model.

Here's a code sample to show what happens.
  • Try typing something into the field, then press "Show model", you will see that the model has been updated. Good
  • Now press "formPanel.clear()". The field is cleared but the model is unchanged. Not good.
  • Same with "formPanel.reset()". The field is reset to its original value, but the model is unchanged. Also not good. On a side note, the field's original value is taken from the field's value when the field is first rendered, not when the field gets bound to a property as one might expect; so if you want reset to actually reset the field to the original model's values, you need to manually call setOriginalValue().
  • Now press "setValue". The field's displayed value is updated, but again the model is unchanged. Again, not good.
Code:
package client.testgxtbindings.client;

import com.extjs.gxt.ui.client.binding.FormBinding;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class TestGXTBindings implements EntryPoint {


    private static class MyModel extends BaseModel {
        public static final String SOME_PROPERTY = "property";
        public String getProperty() {
            return get(SOME_PROPERTY);
        }
        public void setproperty(String value) {
            set(SOME_PROPERTY, value);
        }
    }

    /**
     * This is the entry point method.
     */
    public void onModuleLoad() {
        final FormPanel formPanel = new FormPanel();

        final TextField<String> textField = new TextField<String>();
        textField.setName(MyModel.SOME_PROPERTY);
        textField.setFieldLabel("Property");
        textField.setValue("original value");
        formPanel.add(textField);

        FormBinding formBinding = new FormBinding(formPanel);
        formBinding.autoBind();

        final MyModel model = new MyModel();
        model.setproperty("some text");
        formBinding.bind(model);

        formPanel.add(new Button("formPanel.clear()") {
            {
                addSelectionListener(new SelectionListener<ComponentEvent>() {
                    public void componentSelected(ComponentEvent ce) {
                        GWT.log(((Button)ce.component).getText(), null);
                        formPanel.clear();
                        GWT.log("property=" + model.getProperty(), null);
                    }
                });
            }
        });

        formPanel.add(new Button("formPanel.reset()") {
            {
                addSelectionListener(new SelectionListener<ComponentEvent>() {
                    public void componentSelected(ComponentEvent ce) {
                        GWT.log(((Button)ce.component).getText(), null);
                        formPanel.reset();
                        GWT.log("property=" + model.getProperty(), null);
                    }
                });
            }
        });

        formPanel.add(new Button("textField.setValue(\"qwertz\")") {
            {
                addSelectionListener(new SelectionListener<ComponentEvent>() {
                    public void componentSelected(ComponentEvent ce) {
                        GWT.log(((Button)ce.component).getText(), null);
                        textField.setValue("qwertz");
                        GWT.log("property=" + model.getProperty(), null);
                    }
                });
            }
        });

        formPanel.add(new Button("Show model") {
            {
                addSelectionListener(new SelectionListener<ComponentEvent>() {
                    public void componentSelected(ComponentEvent ce) {
                        GWT.log(((Button)ce.component).getText(), null);
                        GWT.log("property=" + model.getProperty(), null);
                    }
                });
            }
        });


        RootPanel.get().add(formPanel);



    }

}