cx:component

Purpose

An instance of a component class. The cx:component element can create a new component or widen an existing one. Widening a component means extending the set of components that are available for implicit linking.

Contained by

Contains

Attribute groups

Attributes

Attribute Description Type Default Options Use
component-id The component identifier. On the server, it is used to specify explicit links between components and supporting functionality. On the client, it is used to register and link components and supporting code. If this attribute is not specified, then it defaults to the value of the id attribute. xs:NCName     optional 
class-ref

The optional reference to the component class. If not specified, then the component class must be defined within this instance.

Note:

This attribute has been deprecated in favor of the type attribute.

xs:IDREF     deprecated 
type The optional (but recommended) way to specify the type of component (i.e. the name of the component class) that element creates. xs:QName     optional 
widen Specifies a component-id reference to a component instance. The component instance can be a built-in component, or a custom component. The linked components will be available for implicit linking. xs:IDREF     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