cx:ref

Purpose

References a component.

Contained by

Attributes

Attribute Description Type Default Options Use
component The reference to a component. xs:IDREF     optional 
name The name of the reference. xs:string     required 

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