Dynamic View Services > Implementing a Representation Model > Implementing a Tree Representation Model > Component-to-Server Updates
 
Component-to-Server Updates
Each time a component needs to modify a representation directly, it should notify the server of these modifications. However, only the events that may have an impact on the server objects or on the view to which the current representation is related actually need to be notified.
In this Tree example, the server needs to be notified when the following events occur:
*The user has edited the label of a tree gadget item.
*A tree gadget or tree gadget item has been deleted.
*The user has inserted a new gadget item in the tree.
*A tree gadget item has been moved within the tree or to another tree.
The insertion of a new object and drag operations are discussed in the sections “References”. and “Collectors”..
The first two kinds of events are discussed further in this section.
Editing the Label of a Tree Gadget Item
When the label of a tree gadget item is edited, the event must be forwarded by the gadget item to the representation object TreeItemR. The way the event is actually forwarded is component-specific.
With a graphical component, forwarding is usually achieved through callbacks. Thus, it is assumed that the onSetLabel function is called as a callback on the TreeItemR object when the label of the associated tree gadget item is edited. The onSetLabel function can be implemented this way:
void TreeItemR::onSetLabel(IlsString value)
{
onUpdate(getAttributeId("label"),value);
}
The function onUpdate used here is one of the callback functions defined by the class IlsRpObject to notify the server. It takes the identifier and value of the modified attribute as its arguments. The identifier is returned by the function IlsRpObject::getAttributeId, which passes as a parameter the attribute name as it is used in the dynamic-view type specification. For efficiency reasons, we recommend that you store this identifier rather than accessing the function getAttributeId each time the function onSetLabel is called.
Deleting a Gadget Item
A representation object created by the server can be deleted in two ways:
*either indirectly through a server notification cycle,
*or locally by the component.
Deletion by the Server
In that case, a deletion event is notified to the server, which then cuts the server object associated with the representation object. In return (and only if the operation is valid), a server notification request triggers the destruction of the representation object.
In the current example, the deletion event must call the callback function onDelete, which in turn requests the deletion of the corresponding server object by calling the virtual member function IlsRpObject::onSuppress.
void TreeItemR::onDelete()
{
  onSuppress(IlsFalse);
}
Note: To notify the server that a representation object has been removed from a collection, the function IlsRpObject::rmFromCollection should be called instead of onSuppress. This function rmFromCollection cuts the server object only if the collector is associated with an ownership relation.
Local Deletion
The representation object is deleted locally at component level by a call to the function IlsRpObject::onSuppress(IlsTrue). Therefore, the component will not be notified of the deletion event by the server. However, if the transaction is rolled back by the server, the object will be created again on the component side.
Deriving a Tree Representation Type
As a rule, any dynamic view instantiated in the server is associated with a single representation in a single component. By default, the representation is an instance of the class IlsRepresentation. However, you can specify another type of representation. For example, any dynamic view type specified using the Rogue Wave Server Studio graphical interface associates a representation of type IlsSwRepresentation.
A representation type must:
*Derive directly or transitively from the class IlsRepresentation.
*Include specific server declarations made via the macro ILS_REPRESENTATION_DECL in its declaration;
*Define a constructor that takes the following parameters:
*The reference to the component to which the representation belongs (that is, to an instance of the class IlsMvComponent)
*The reference to the dynamic representation model associated with the dynamic view type (that is, to an instance of the class IlsRpModel).
In the current example, it was decided to implement a specific representation class for the tree representation, as reflected by the code sample below. This class buffers the attributes of the tree item being currently created. It also defines a function to set the resource file required for displaying the tree (font, item bitmap, color, etc.):
class TreeRepresentation: public IlsRepresentation
{
public:
TreeRepresentation(IlsMvComponent& c,const IlsRpModel& m)
: IlsRepresentation(c,m), _curtOwner(0), _curtItemOwner(0) {}
void setResourceFile(IlsString fileName);
private:
TreeR* _curtTreeOwner;
TreeItemR* _curtItemOwner;
IlsString _curtLabel;
ILS_REPRESENTATION_DECL(TreeRepresentation)
}
The class IlsRepresentation derives from the class IlsRpObject. Therefore, this class is also a representation object type. As such, it can be instantiated using attributes and must be registered with the representation model interpreter. In the current example, the class TreeRepresentation is registered with the attribute resourceFile, which makes it possible to define the resource file used by the tree in a dynamic view type specification:
ILS_REPRESENTATION_BEGIN(TreeRepresentation)
ILS_RP_ATTR_STRING(TreeRepresentation,resourceFile,setResourceFile)
ILS_REPRESENTATION_END(TreeRepresentation)

Version 5.8
Copyright © 2014, Rogue Wave Software, Inc. All Rights Reserved.