cx:client-reference

Purpose

Defines the client-side representation of the reference used for generating the JavaScript code needed to perform the binding.

The setter, field and property attributes are mutually exclusive. If none of them is specified, then it behaves as if the field attribute was set to the name of the reference.

Contained by

Attributes

Attribute Description Type Default Options Use
field The name of the field in the client component instance into which the reference is to be stored. xs:string     optional
property The name of the observable property in the client component instance into which the reference is to be stored. The component must mixin the V$.cf2.OPSet class provided by the cf2:ObservablePropertySet component. It is the responsibility of the client-side implementation to make sure that the property has been created during the linking phase of the page construction process. xs:string     optional
setter The name of the single argument method which is to be used to set the reference on the client component instance. This is useful when the value being set needs processing before it is stored in an object. xs:string     optional

Example

<html xmlns="http://www.w3.org/2002/06/xhtml2"
  xmlns:cf2="http://www.volantis.com/xmlns/2009/07/cf2"
  xmlns:cst="http://www.volantis.com/xmlns/2009/07/cf2/template"
  xmlns:cx="http://www.volantis.com/xmlns/2010/07/cf2/cx"
  xmlns:mcs="http://www.volantis.com/xmlns/2006/01/xdime/mcs"
  xmlns:my="http://www.mycomponents"
  xmlns:ui="http://www.volantis.com/xmlns/2009/07/cf2/ui"
  xmlns:car="http://www.cars/">
  <head>
    <title>Custom Component Example</title>
    <meta property='cf2:validation-mode' about='#PoorDriver'>strict</meta>
    
    <!--
     ! This page makes use of Observable Property Prototype and so should explicitly indicate
     ! that by providing an mcs:script element that references an mscr file that imports those
     ! features. Instead this relies on the ui:button element importing the required feature
     ! into the page. This is probably not the best way but is allowed as a button is
     ! explicitly defined as importing that feature.
     !-->
    
    <!--
     ! Car Class
     !-->
    <cx:component-class defines="reference-types" name="car:Car" id="Car">
      <mcs:script type="text/javascript">
        // ==================================================
        // JavaScript representation of Car
        // ==================================================
        var Car = V$.Class.create();
        Car.mixin(V$.cf2.OPSet);
        V$.cf2.OPProto.add(Car, "owner", {});
        Car.methods({
          initialize: function() {
            V$.cf2.OPProto.init(this);
          },
          setEngine: function(engine) {
            this.engine = engine;
          },
          start: function() {
            // Start engine.
          }
        });
      </mcs:script>
      
      <cx:client-class name="Car" start-method="start"/>
      
      <cx:reference name="engine" structural-relationship="child"
        component-types="car:Engine">
        <cx:client-reference setter="setEngine"/>
      </cx:reference>
      
      <cx:reference name="steeringWheel" structural-relationship="child"
        component-types="car:SteeringWheel">
        <cx:client-reference field="steeringWheel"/>
      </cx:reference>
      
      <cx:reference name="owner" structural-relationship="parent"
        component-types="car:Owner">
        <cx:client-reference property="owner"/>
      </cx:reference>
      
    </cx:component-class>
    
    <!--
     ! Engine class
     !
     ! An abstract class (no JavaScript implementation), that defines an API that other engines
     ! implementations have to follow. At the moment there is no way within the component class
     ! to define the API (in terms of methods, parameters, etc. However, future enhancements
     ! may add that support.
     !-->
    <cx:component-class name="car:Engine" defines="reference-types"/>
    
    <!--
     ! Diesel Engine class
     !
     ! A concrete implementation of an engine.
     !-->
    <cx:component-class name="car:DieselEngine" implements="car:Engine"
      defines="reference-types" id="Diesel">
      <mcs:script type="text/javascript">
        // ==================================================
        // JavaScript representation of Diesel Engine
        // ==================================================
        var DieselEngine = V$.Class.create();
        DieselEngine.methods({
          initialize: function(name) {
            this.name = name;
          }
        });
      </mcs:script>
    </cx:component-class>
    
    <!--
     ! Steering Wheel Class
     !
     ! A concrete implementation of a steering wheel.
     !-->
    <cx:component-class name="car:SteeringWheel" defines="reference-types" id="SteeringWheel">
      <mcs:script type="text/javascript">
        // ==================================================
        // JavaScript representation of Steering Wheel
        // ==================================================
        var SteeringWheel = V$.Class.create();
        SteeringWheel.methods({
          initialize: function(color, texture) {
            this.color = color;
            this.texture = texture;
          }
        });
      </mcs:script>
    </cx:component-class>
    
    <!--
     ! Car Owner Class
     !
     ! A concrete implementation of a car owner.
     !-->
    <cx:component-class name="car:Owner" defines="reference-types">
      <mcs:script type="text/javascript">
        // ==================================================
        // JavaScript implementation of Owner
        // ==================================================
        var Owner = V$.Class.create();
        Owner.mixin(V$.cf2.OPSet);
        V$.cf2.OPProto.add(Owner, "car", {});
        V$.cf2.OPProto.add(Owner, "name", {});
        Owner.methods({
          initialize: function(name) {
            V$.cf2.OPProto.init(this);
            this.setName(name);
          }
        });
      </mcs:script>
    </cx:component-class>
    
  </head>
  <body>
    
    <!--
     ! Steering Wheel Instance
     !-->
    <cx:component component-id="PinkFluffySteering" class-ref="SteeringWheel">
      
      <!--
       ! Must specify in each component instance how to construct a steering wheel as no
       ! name was specified on the cx:client-class element.
       !-->
      <cx:client-create>
        return new SteeringWheel("pink", "fluffy");
      </cx:client-create>
    </cx:component>
    
    <!--
     ! Engine instance
     !-->
    <cx:component component-id="Zetec" class-ref="Diesel">
      
      <!--
       ! Must specify in each component instance how to construct a diesel engine as no
       ! name was specified on the cx:client-class element.
       !-->
      <cx:client-create>
        return new DieselEngine("zetec");
      </cx:client-create>
    </cx:component>
    
    <!--
     ! Poor refers to how much money the driver has to spend on cars, not the quality of
     ! their driving. A poor driver is one that can only have at most a single car.
     !-->
    <cx:component id="PoorDriver">
      
      <!--
       ! An anonymous (no name, no id) class.
       !
       ! The encapsulating component does not specify class-ref attribute so it is bound to
       ! this class.
       !-->
      <cx:component-class defines="reference-types" implements="car:Owner">
        
        <!--
         ! Car references are optional - due to min-occurs = 0
         !-->
        <cx:reference name="car" structural-relationship="child" component-types="car:Car"
          min-occurs="0">
          <cx:client-reference setter="setCar"/>
        </cx:reference>
      </cx:component-class>
      
      <cx:client-create>
        // Create the client side representation of a poor driver.
        return new Owner("Willy");
      </cx:client-create>
      
      
      <cx:component id="CompanyCar" class-ref="Car">
        <cx:ref name="engine" component="Zetec"/>
        <cx:ref name="steeringWheel" component="PinkFluffySteering"/>
        <!--
         ! Owner is implicitly bound to containing component. 
         !-->
        
        <cx:client-start>
          // Make sure that the car owner name is appropriate to the steering wheel.
          c.setOwner('Shirley');
        </cx:client-start>
      </cx:component>
      
    </cx:component>
    
    <div>
      <cst:value property-value="PoorDriver#name" path="."/> has a
      <cst:value property-value="PoorDriver#car" path="steeringWheel.color"/>
      <cst:value property-value="PoorDriver#car" path="steeringWheel.texture"/>
      steering wheel and a <cst:value property-value="PoorDriver#car" path="engine.name"/> engine!
      <div>
        <ui:button>
          <cf2:on event="cf2:activate" set="PoorDriver#name" string="Fred"/>
          Rename to Fred
        </ui:button>
      </div>
    </div>
    
  </body>
</html>

Related topics