+ All Categories
Home > Documents > Coldbox developer training – session 5

Coldbox developer training – session 5

Date post: 19-Jul-2015
Category:
Upload: billie-berzinskas
View: 235 times
Download: 4 times
Share this document with a friend
38
Coldbox Developer Training Session 5 bill berzinskas UNC-CH Office of Research Information Systems
Transcript
Page 1: Coldbox developer training – session 5

Coldbox Developer Training Session 5

bill berzinskas

UNC-CH Office of Research Information Systems

Page 2: Coldbox developer training – session 5

Review last weeks assignment

• Create Unit Tests

• Create Model CFC‟s w/ BaseGateway

Page 3: Coldbox developer training – session 5

Overview

• Talk about the “handler”

• Look at how to use WireBox inside a

handler

• Explore “Integration Testing”

Page 4: Coldbox developer training – session 5

MVC – The Controller (Handler)

• Event handlers are synonymous to the

word Controller in the MVC design

pattern. So every time you hear event

handler, you are taking about a controller.

• These event handlers carry the task of

controlling your application flow, calling

business logic, preparing a display to a

user and pretty much controlling flow.

Page 5: Coldbox developer training – session 5

MVC – The Controller (Handler)

Simple example:

component{

function index(event,rc,prc){

return "Hi from controller land!";

}

}

Page 6: Coldbox developer training – session 5

MVC – The Controller (Handler)

• Handlers reside in the handlers folder and

can be organized by “package” by placing

like CFCs together inside a folder• Handlers/department/roles.cfc

• Handlers/department/

• You can also declare a

HandlersExternalLocation setting in your

Coldbox.cfc• Common.handlers

Page 7: Coldbox developer training – session 5

MVC – The Controller (Handler)

Handler Registration

• At application startup, the framework registers all

the valid event handler CFCs in these locations

(plus handlers inside of modules).

• Two settings are provided to “reload” mappings

in development environments – these may

cause strange errors in high load or ajax

scenarios

coldbox.handlersIndexAutoReload = true;

coldbox.handlerCaching = false;

Page 8: Coldbox developer training – session 5

MVC – The Controller (Handler)Rules and Anatomy of an Event Handler

• They can be simple CFCs or inherit from our

base handler: coldbox.system.EventHandler.

• They must exist in the correct handlers directory

under your application.

• They must NOT contain any business logic, that

is what the model or business layer is for.

Page 9: Coldbox developer training – session 5

MVC – The Controller (Handler)Rules and Anatomy of an Event Handler

• They must have public methods (actions) that

will respond to ColdBox events.

• Private events have an access type of private

and can only be called from within the

application by using the runEvent() method.

Page 10: Coldbox developer training – session 5

MVC – The Controller (Handler)Rules and Anatomy of an Event Handler

• Handlers are cached by default, unless the

handler caching setting is off. You can configure

persistence via metadata.

• You can easily wire up dependencies in your

handler by using the WireBox injection DSL.

Page 11: Coldbox developer training – session 5

MVC – The Controller (Handler)Composed Properties

• It is imperative that you realize that there is a

great object model behind every event handler

that will enable you to do your work more

efficiently.

• The following are the composed properties

every event handler has in their variables scope,

you do not need to do anything to retreive them,

they are already there :)

Page 12: Coldbox developer training – session 5

MVC – The Controller (Handler)Composed Properties

Page 13: Coldbox developer training – session 5

MVC – The Controller (Handler)Featured Properties

• Each event handler can also exhibit

several feature properties that can be

tuned to alter the behavior of the local

AOP interception points, event caching

and HTTP method security.

– aroundHandler_only /aroundHandler_except

– preHandler_only / preHandler_except

– postHandler_only / postHandler_except

– allowedMethods = {Get, POST, Delete}

Page 14: Coldbox developer training – session 5

MVC – The Controller (Handler)Anatomy of an Event Handler Action

• function sayHello(event,rc,prc){

– event : The request context object reference

– rc : A reference to the request collection inside of the request context object

– prc : A reference to the private request collection inside of the request context

object

Page 15: Coldbox developer training – session 5

MVC – The Controller (Handler)Get/Set Request Values

• We all need values in our applications, and we will

interact with the request context

• RC (and PRC) can

– hold data from our model layer so our views can display it

– retreive data from a user's request

Page 16: Coldbox developer training – session 5

MVC – The Controller (Handler)Get/Set Request Values

• You will either interact with the event object to get/set

values OR put/read values directly via the received rc

and prc references.

• We recommend using the references as structures are

much faster than method calls.

– Prefer: Rc.users = userService.get();

• However, the event object should not be discarded as it

has some pretty cool and funky methods of its own.

Page 17: Coldbox developer training – session 5

MVC – The Controller (Handler)“Event” Object

//set a value for views to use

event.setValue("name", "Luis");

// retrieve a value the user sent

event.getValue("name");

// retrieve a value the user sent or give me a default value

event.getValue("isChecked",false);

//param a value

event.paramValue("user_id","");

//remove a value

event.removeValue("name");

Page 18: Coldbox developer training – session 5

MVC – The Controller (Handler)“Event” Object

//check if value exists

if( event.valueExists("name") ){ }

// set a view for rendering

event.setView('blog/index');

// set a layout for rendering

event.setLayout('main');

// set a view and layout

event.setView(view="blog/userinfo",layout="ajax");

Page 19: Coldbox developer training – session 5

MVC – The Controller (Handler)Setting Views / Layouts

The event object is the object that will let you set the views

that you want to render, so please explore its API in the

CFC Docs

Event.setView(„myView‟) -- NO .cfm

Event.setView(„user/detail‟)

While views can be loaded inherently, it is certainly useful

to be able to switch views programaticaly (ex. user A gets

View A and user B gets View B for a given event)

Page 20: Coldbox developer training – session 5

MVC – The Controller (Handler)Setting Views / Layouts

We recommend that you maintain a consistent naming and location

schema between views and your handler and actions, often called

implicit views.

So if you have an incoming event called: users.index then make sure

in your views folder you have:

Views

-users

--index.cfm

This way debugging is much easier and also Implicit Views can be

used. Implicit views means that you won't use a event.setView() to

specify what view to render. It is implied the view to render will be the

same as the executing event.

Page 21: Coldbox developer training – session 5

MVC – The Controller (Handler)Relocating

The framework provides you with a method that you can use to relocate

to other events thanks to the framework super type object

It is extremely important that you use this method when relocating

instead of the native ColdFusion methods as it allows you to gracefully

relocate to other events or external URIs.

By graceful, we mean it does a lot more behind the scenes like making

sure the flash scope is persisted, logging, post processing interceptions

can occur and safe relocations.

Page 22: Coldbox developer training – session 5

MVC – The Controller (Handler)Relocating

setNextEvent

eventThe name of the event or SES pattern to relocate to, if not passed, then it will use the default

event found in your configuration file. (Mutex with URI and URL)

URL The absolute URL to relocate to (Mutex with URI and event)

URI The relative URI to relocate to (Mutex with event and URL)

queryString The query string to append to the relocation. It will be converted to SES if SES is used.

addToken Whether to add the cf tokens or not. Default is false

persistA comma-delimited list of request collection key names that will be flash persisted in the

framework's flash RAM and re-inflated in the next request.

persistStructA structure of key-value pairs that will be flash persisted in the framework's flash RAM and re-

inflated in the next request.

ssl Flag indicating if redirect should be done in ssl mode or not

baseURLIf used, then it is the base url for normal syntax redirection instead of just redirecting to the

index.cfm

postProcessExempt Do not fire the postProcess interceptors

statusCode The status code to relocate with

Page 23: Coldbox developer training – session 5

MVC – The Controller (Handler)Rendering Data

You can also use the event.renderData() method to render and

marshal data directly from an event handler without the need to set a

view for rendering.

Out of the box ColdBox can marshall data

(structs,queries,arrays,complex or even ORM entities) into the following

output formats: – XML, JSON, JSONP, HTML, TEXT, WDDX, PDF,Custom

event.renderData(type="json",data=qUsers)

Page 24: Coldbox developer training – session 5

MVC – The Controller (Handler)Model Integration

As mentioned in some of the early sessions, Wirebox allows us to inject

CFC‟s **NEARLY** anywhere!

component{

// Injection

property name=“model:funkyService" inject;

function index(event,rc,prc){

prc.data = funkyService.getFunkyData();

event.renderData(data=prc.data,type="xml");

}

}

Page 25: Coldbox developer training – session 5

MVC – The Controller (Handler)Model Integration

Coldbox offers a few function to allow us to consume CFC by

REQUESTING them

Via Façade:

prc.data = getModel("FunkyService").getFunkyData();

Directly to Wirebox:

prc.data = wirebox.getInstance("FunkyService").getFunkyData();

Both approaches do exactly the same, in all reality getModel() does a

wirebox.getInstance(), it is a facade method that is easier to

remember.

Page 26: Coldbox developer training – session 5

MVC – The Controller (Handler)Model Integration

Wirebox also offers you the capability to bind incoming

FORM/URL/REMOTE data into your model objects by convention.

populateModel(„myBean‟, rc);

This will try to match incoming variable names to setters or properties

in your domain objects and then populate them for you.

Page 27: Coldbox developer training – session 5

MVC – The Controller (Handler)Validation

Coldbox offers “ValidBox” to allow for annotation based validation

We currently recommend “ValidateThis”, but ValidBox is being

researched!

Page 28: Coldbox developer training – session 5

MVC – The Controller (Handler)Executing Events

Apart from executing events from the URL/FORM or Remote

interfaces, you can also execute events internally, either public or

private from within your event handlers

runEvent(event, prepostExempt, private, eventArguments)

Page 29: Coldbox developer training – session 5

MVC – The Controller (Handler)Testing Controllers

• ColdBox offers two approaches to testing your event handlers:

– Integration Testing : Tests everything top-down in your application

– Handler Testing : Like unit testing for handlers

• Integration testing will virtually create your application and execute

the event you want. Thus, loading everything in a typical request

and simulate it.

• The handler testing just tests the event handler in isolation much like

unit testing does.

Page 30: Coldbox developer training – session 5

MVC – The Controller (Handler)Testing Controllers

• To use “Integration testing”, your test should extend

coldbox.system.testing.baseIntegrationTest

• Events can be executed with the execute() function

function testindex(){

var event = execute("general.index");

assertEquals("Welcome!", event.getValue("welcomeMessage"));

}

• We can then retrieve the event object and thus the requestCollection

to use during our assertions

var event = execute("general.dspLogin");

var prc = event.getCollection(private=true);

assertEquals("general.dspLogin", prc.currentView );

Page 31: Coldbox developer training – session 5

MVC – The Controller (Handler)Questions??

Page 32: Coldbox developer training – session 5

MVC – The Controller (Handler)Assignment

• Add to existing unit test to run GET with a

nominatorPID argumentresults=this.myComp.get(nominatorPID='711933859');

assertTrue(isQuery(results));

• Run – FAIL!

• Add NominatorPID argument to

recommendationGateway

• Run – PASS!

Page 33: Coldbox developer training – session 5

MVC – The Controller (Handler)Assignment

• Create a simpler handler CFC for

recommendation.submission

– Add index function• We don‟t need to “setView” because we‟ve already got an implicit

view in place from last week

• Add an INIT method to recommendationGateway

<cffunction name='init' returnType="any" output="false">

<cfargument name="datasource"

inject="coldbox:datasource:main">

<cfreturn super.init(argumentCollection = arguments)>

</cffunction>

Page 34: Coldbox developer training – session 5

MVC – The Controller (Handler)Assignment

• Autowire recommendationGateway.

– Add the following after the CFCOMPONENT tag in your handler

• <cfproperty name=“recommendations”

inject=“model:recommendation.recommendationGateway”>

• Our “index” handler will call recommendationGateway for data, so

we‟ll add an assertion to

test/integration/recommendation/submissionTest.cfc testIndex

method

Prc = event.getCollection(private=true);

assertTrue(isDefined(„prc.recommendations‟));

assertTrue(isQuery(prc.recommendations));

Page 35: Coldbox developer training – session 5

MVC – The Controller (Handler)Assignment

• Run integration tests – FAIL!!

• Get the data into the handler

<cfset prc.recommendations =

recommendations.get(session.pid)>

• Run Test – PASS!

Page 36: Coldbox developer training – session 5

MVC – The Controller (Handler)Assignment

• Open the recommendation/submission/index.cfm view

– Remove GetFTARs CFINCLUDE

– Begin removal of “getSubmissions_CFCRet” array• Its now a query, so adjust calls like ArrayLen, CFLOOP, [cnt]

• Move the relocation and access checks code into your handler,

using setNextEvent

<cfif !prc.recordcount><cfset setNextEvent(url=„submit.cfm‟)>

</cfif>

<cfif structKeyExists(session,"nominateList") and len(trim(session.nominateList)) eq

0><cfset messageBox.warn(„You do not have access to submit nominations. Please contact Lou Anne

Phelps at the Graduate School. ([email protected]).“)>

<cfset setNextEvent(„general.index‟)>

</cfif>

Page 37: Coldbox developer training – session 5

MVC – The Controller (Handler)Assignment

• We‟ve just “factored up” the call for submission list data and created

/ updated the relevant tests! A small achievement that‟s taken us a

while, but the start of something beautiful!

Page 38: Coldbox developer training – session 5

MVC – The Controller (Handler)Next Week

• FORMS!


Recommended