Object Factory

As seen in the Creating a Widget, a widget may be created using scout.create. When using this function, the call is delegated to the ObjectFactory.

The ObjectFactory is responsible to create and initialize a Scout object. A typical Scout object has an objectType and an init function. But actually any kind of object with a constructor function may be created.

To create and initialize a new object, the objectType needs to be passed. The objectType is either a class reference pointing to the object you want to create or the name of the object. When using a class reference, the return value will be typed, so the IDE can assist you with code completion, which makes it the recommended approach. When using the name of the object (string based object type), the object needs to be registered using ObjectFactory.get().registerNamespace.

Listing 1. Creating an object by class reference
import {scout, Table} from '@eclipse-scout/core';

let table = scout.create(Table, model);
Listing 2. Creating an object by name
import {scout} from '@eclipse-scout/core';

let obj = scout.create('scout.Table', model);

If you use a string based object type, the object is created using naming convention by default. This means when calling scout.create('scout.Table', model), the scout namespace is searched for a class called Table. Since scout is the default namespace, it may be omitted. So calling scout.create('Table', model) has the same effect.

After creating the object, it will be instantiated and the init function called, if there is one. The model is passed to that init function. So instead of using scout.create you could also use the following code:

Listing 3. Creating an object without the ObjectFactory
import {Table} from '@eclipse-scout/core';
let table = new Table();
table.init(model);

This will work fine, but you will lose the big benefit of the ObjectFactory: the ability to replace existing classes. So if you want to customize the default Table, you would likely extend that table and override some functions. In that case you need to make sure every time a table is created, your class is used instead of the default. To do that you have to register your class in the ObjectFactory with the objectType Table. If scout.create('Table') is called the object factory will check if there is a class registered for the type Table and, if yes, that class is used. Only if there is no registration found, the default approach using the naming convention is performed.

In order to register your class, you need a file called objectFactories and add that to your JavaScript module (e.g. index.ts). The content of that file may look as following:

Listing 4. Adding a new object factory registration
import {CustomTable} from './index';
import {scout} from '@eclipse-scout/core';

scout.addObjectFactories({
  'Table': () => new CustomTable()
});

This will simply add a new factory for the type Table to the list of existing factories. From now on, yourproject.CustomTable will be instantiated every time a Table needs to be created.

This replacement also works if scout.create is used with class references (which is the recommended approach). So, scout.create('Table') as well as scout.create(Table) will return a new CustomTable.

Object Factory Hints

When creating a new object using the ObjectFactory, the object can automatically be extended by the following properties:

  • objectType: the string based object type of the created object. This works only if the object has been registered using ObjectFactory.get().registerNamespace.

  • id: a generated ID based on the UI sequence (see ObjectIdProvider.createUiSeqId), if the model does not already contain an id.

Whether these properties are added is controlled by the objectFactoryHints decorator. This decorator can be added to the class of the object that is supposed to be created by the object factory. It provides two options:

  • ensureObjectType: specifies whether the string based object type needs to be resolved and assigned. Default is true.

  • ensureId: specifies whether a unique id needs to be assigned if the object does not already have one. Default is false.

The decorator is optional. If neither the class nor a super class is decorated, the default hints will be applied.