public interface DataPath NOTE: the dataPath feature is intended to help certain legacy architectures, such as systems that work in terms of exchanging large messages with several different entity types in one message, and are incapable of providing separate access to each entity type. Don't use dataPath if this is not your situation.
If you are not forced by legacy issues to use hierarchical data structures, we recommend: For example, when representing a sales order with a "deliveryAddress" (consisting of multiple fields), you'd typically want an "orders" dataSource to define the fields for the order as a whole, and an "address" dataSource to define the structure of the deliveryAddress object. It may seem like a good idea to work with a single hierarchical order object, where the "deliveryAddress" attribute is set to a sub-object that matches the structure defined in the "address" dataSource. DataPaths could be used to extract individual address fields for editing in a form alongside other fields from the order, and edits would be saved via a simple "add" or "update" operation, passing in the modified nested data object. In fact, this has a number of disadvantages. Since there is no call to the "update" operation on the "address" subobject, the address will be modified without the normal features of a dataSource update. You can't specify Loading and saving nested data objects as a single hierarchical block also offers no advantages in terms of performance or simplicity. Loading arrays of related objects (such as all LineItems in an Order) as a hierarchical object has the further drawback that paging cannot be used for the list of related objects, and all such objects will not participate in
In short, we do not recommend structuring your data as a hierarchy of nested data objects and using dataPath to navigate these structures unless you are forced to by a legacy system that doesn't allow separate operations on each entity type. DataSourceField.valueXPath.security rules, DMI logic, request modifiers, and no logging or auditing will run.
The same "bypassing" problem occurs, in perhaps worse form, if a subobject does not yet exist and the framework creates it automatically, skipping a DataSource "add" operation that may have established defaults, not been allowed for the user, etc.
The queuing system makes it extremely easy to load and save multiple types of entities in a single HTTP request, and takes far less code to implement properly as multiple DataSource operations, with equivalent or better performance. automatic cache synchronization.
How to use dataPaths
Each dataPath string is a slash-delimited set of field identifiers, for example "id1/id2/id3". DataPaths may be applied directly to a component, and/or to a databound component field specification. A datapath denotes a path to a nested field value in a hierarchical structure, giving developers the opportunity to easily view or edit nested data structures. Specifically:
[
{ name:"name" },
{ name:"street", dataPath:"address/street" }
]
If the "name" field is set to "Joe Smith" and the "street" field is set to "1221 High Street", when the values for this form are retrieved via a getValues() call they will return an object in the following format:
{name:"Joe Smith", address:{street:"1221 High Street"}}
For databound components, dataPath also provides a way to pick up field attributes from nested dataSources. Given the following dataSource definitions:
DataSource addressDS = new DataSource();
DataSourceField street = new DataSourceField();
street.setName("street");
DataSourceField city = new DataSourceField();
city.setName("city");
DataSourceField state = new DataSourceField();
state.setName("state");
DataSourceField zip = new DataSourceField();
zip.setName("zip");
addressDS.setFields(street, city, state, zip);
DataSource contactsDS = new DataSource();
DataSourceField name = new DataSourceField();
name.setName("name");
DataSourceField email = new DataSourceField();
email.setName("email");
DataSourceField organization = new DataSourceField();
organization.setName("organization");
DataSourceField phone = new DataSourceField();
phone.setName("phone");
DataSourceField address = new DataSourceField();
address.setName("address");
address.setType(addressDS);
contactsDS.setFields(name, email, organization, phone, address);
and a databound component bound to the 'contacts' dataSource, specifying a field with a dataPath of "address/street" would ensure the field attributes were derived from the "street" field of the 'Address' dataSource. dataPaths are also cumulative. In other words if a component has a specified dataPath, the dataPath of any fields it contains will be appended to that component level path when accessing data. For example the following form:
DynamicForm form = new DynamicForm();
form.setDataPath("contact");
TextItem field1 = new TextItem();
field1.setDataPath("address/email");
form.setFields(field1);
Might be used to edit a data structure similar to this: {contact:{name:'Ed Jones', address:{state:"CA", email:"ed@ed.jones.com"}}} Nested canvases can also have dataPaths specified, which will similarly be combined. See the Canvas.dataPath attribute for more information and examples of this.