Created
March 25, 2014 11:07
Ask Ben: Using ColdFusion Components As Return Types, Argument Types, And Property Types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfcomponent | |
output="false" | |
hint="I provide application settings and event handlers."> | |
<!--- Define the application. ---> | |
<cfset this.name = hash( getCurrentTemplatePath() ) /> | |
<cfset this.applicationTimeout = createTimeSpan( 0, 0, 0, 20 ) /> | |
<!--- | |
Get the root directory of the application. This will | |
be needed to define the subsequent app-specific mappings. | |
---> | |
<cfset this.rootDirectory = getDirectoryFromPath( | |
getCurrentTemplatePath() | |
) /> | |
<!--- Define application-specific mappings. ---> | |
<cfset this.mappings[ "/com" ] = (this.rootDirectory & "model/" ) /> | |
<cfset this.mappings[ "/vo" ] = (this.rootDirectory & "vo/" ) /> | |
<!--- Define page request settings. ---> | |
<cfsetting | |
showdebugoutput="false" | |
/> | |
</cfcomponent> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Import the "vo" name space. | |
// NOTE: The name space that we are importing is an application- | |
// specific mapping and that this name-space is used to define the | |
// return type of one of the functions below. | |
import "/vo.*"; | |
// Define the component. | |
component | |
output="false" | |
accessors="true" | |
hint="I am a contact entity." | |
{ | |
// Define properties. | |
property | |
name="name" | |
type="string" | |
default="" | |
validate="string" | |
validateParams="{ minLength = 1, maxLength = 30 }" | |
hint="I am the full name." | |
; | |
property | |
name="lastValueObject" | |
type="vo.ValueObject" | |
hint="I am the last requested value object." | |
; | |
/** | |
* Define constructor. Notice that the return type of the | |
* ColdFusion component uses BOTH the app-specific mapping | |
* to "com" as well as the multi-part, dot-delimitted path | |
* to THIS component. | |
* | |
* @access public | |
* @output false | |
* @hint I return an initialized component. | |
**/ | |
com.Contact function init( | |
string name = "" | |
){ | |
// Store default properties. | |
this.setName( arguments.name ); | |
// Return this object reference. Remember, when used in | |
// conjunction with the NEW keyword, you must explicitly | |
// return the object reference. | |
return( this ); | |
} | |
/** | |
* Notice that in this method, we are defining a local path | |
* to the component (no app-specific mappings) and that the | |
* returnType attribute is being defined in the comments. | |
* | |
* @access public | |
* @returnType Contact | |
* @output false | |
* @hint I return the current contact. | |
**/ | |
function getContact(){ | |
return( this ); | |
} | |
/** | |
* Notice that in this method, the return type "ValueObject" | |
* is only valid becuase our IMPORT command above imported | |
* the app-specific mappings / namespace, "/vo". Notice also | |
* that the default argument value does NOT use the imported | |
* namespace, but rather, refers back to the multi-part, | |
* dot-delimtted mapping path. | |
* | |
* @access public | |
* @returnType ValueObject | |
* @output false | |
* @hint I return a value-object representation of this entity. If you want to, you can pass-in an existing valueObject instance. | |
*/ | |
function getValueObject( | |
valueObject valueObject = new vo.ValueObject() | |
){ | |
// Store local properties into the given value object. | |
arguments.valueObject.set( "name", this.getName() ); | |
// Store the value object as a property. | |
this.setLastValueObject( arguments.valueObject ); | |
// Return populated value object. | |
return( arguments.valueObject ); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--- | |
Import the COM name space (NOTE: This actually maps to the | |
"model" directory thanks to our appliation-specific mappings). | |
---> | |
<cfimport path="com.*" /> | |
<!--- Create a new Contact instance. ---> | |
<cfset tricia = new Contact( "Tricia Smith" ) /> | |
<!--- Rename contact (only to test accessors). ---> | |
<cfset tricia.setName( "Tricia 'the hottie' Smith" ) /> | |
<!--- | |
Get the contact object (to test the return type is enforced | |
as a Contact instance). | |
---> | |
<cfset contact = tricia.getContact() /> | |
<!--- | |
Get the value object (to test that mapped-return type | |
based on the IMPORT command used inside the CFC). | |
---> | |
<cfset valueObject = contact.getValueObject() /> | |
<cfoutput> | |
<!--- Output name contained within value object. ---> | |
Name: #valueObject.get( "name" )#<br /> | |
<!--- Output name contained within LAST value object. ---> | |
Name: #tricia.getLastValueObject().get( "name" )# | |
</cfoutput> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfcomponent | |
output="false" | |
hint="I am a very simple, light-weight value object for any component - I store properties in an expandable map."> | |
<cffunction | |
name="init" | |
access="public" | |
returntype="any" | |
output="false" | |
hint="I return an initialized value object."> | |
<!--- Set up default properties. ---> | |
<cfset variables.propertyMap = {} /> | |
<!--- Return this object reference. ---> | |
<cfreturn this /> | |
</cffunction> | |
<cffunction | |
name="get" | |
access="public" | |
returntype="any" | |
output="false" | |
hint="I return the given property, or property set."> | |
<!--- Define arguments. ---> | |
<cfargument | |
name="name" | |
type="string" | |
required="false" | |
hint="I am the name of the property beging gotten (if omitted, fulle property set is returned)." | |
/> | |
<!--- Check to see if property name was included. ---> | |
<cfif isNull( arguments.name )> | |
<!--- | |
No property was requested; return entire | |
property map. | |
---> | |
<cfreturn variables.propertyMap /> | |
<cfelse> | |
<!--- Return selected property. ---> | |
<cfreturn variables.propertyMap[ arguments.name ] /> | |
</cfif> | |
</cffunction> | |
<cffunction | |
name="set" | |
access="public" | |
returntype="any" | |
output="false" | |
hint="I set the given property."> | |
<!--- Define arguments. ---> | |
<cfargument | |
name="name" | |
type="string" | |
required="true" | |
hint="I am the name of the property." | |
/> | |
<cfargument | |
name="value" | |
type="any" | |
required="true" | |
hint="I am the property value." | |
/> | |
<!--- Set the given property. ---> | |
<cfset variables.propertyMap[ arguments.name ] = arguments.value /> | |
<!--- Return this object reference for method chaining. ---> | |
<cfreturn this /> | |
</cffunction> | |
</cfcomponent> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment