loading table of contents...

5.3.5. Model Beans for Custom Components

When creating complex GUI components, it is good practice to provide an abstract model in the form of a bean to back the view. It is often helpful to provide an ActionScript base class (MyComponentBase below) for the component and extend it by an EXML component, bundling the application logic in the base class. The base class should therefore also take care of building the model bean.

Note however that when creating the Ext JS component configuration in the EXML component, the constructor of the base class has not yet been invoked. Because the component configuration must reference the model to bind the component's states, the model bean must be created before the base class constructor is used. This can be achieved by an accessor method that creates the bean using the call com.coremedia.cms.editor.sdk.editorContext.getBeanFactory().createLocalBean() upon first access. This is shown in the getModel() method below.

import com.coremedia.ui.data.Bean;
import com.coremedia.ui.data.beanFactory;
import mypackage.config.myComponent;
import ext.Panel;

public class MyComponentBase extends Panel {
  ...
  private var model:Bean;

  /**
   * ...
   * @param config the config object
   */
  public function MyComponentBase(config:myComponent = undefined) {
    super(config);
    initModel(config);
    ...
  }

  public function getModel():Bean {
    if (!model) {
      model = beanFactory.createLocalBean();
    }
    return model;
  }

  private function initModel(config:myComponent):void {
    getModel().set('myProperty', ...);
    ...
  }
  ...
}

Example 5.8. Model bean factory method


Given this base class, you can access the model in the EXML class as follows:

<exml:component xmlns:exml="http://www.jangaroo.new/exml/0.8"
                xmlns="exml:ext.config"
                xmlns:ui="exml:com.coremedia.ui.config"
                xmlns:mm="exml:mypackage.config"
                baseClass="MyComponentBase">
  <panel>
    <items>
      ...
      <textfield>
        <plugins>
          <ui:immediateChangeEventsPlugin/>
          <ui:bindPropertyPlugin bidirectional="true">
            <ui:bindTo>
              <ui:valueExpression expression="myProperty"
                                  context="{getModel()}"/>
            </ui:bindTo>
          </ui:bindPropertyPlugin>
        </plugins>
      </textfield>
      ...
    </items>
  </panel>
</exml:component>

Example 5.9. Model bean access


Here a text field is configured to display the value of a property, but of course arbitrary widgets can be used.

In fact, the property is not directly accessed by the plugin, but indirectly through a value expression that, in this case, simply evaluates to a property value. Value expressions will be discussed in the next section.