1. Trang chủ
  2. » Công Nghệ Thông Tin

advanced Flex Application Development Building Rich Media X phần 8 ppsx

51 234 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Building The Jobs Board
Tác giả Omar Gonzalez, Chris Charlton, Hasan
Trường học University of Technology
Chuyên ngành Advanced Flex Application Development
Thể loại Bài báo
Năm xuất bản 2007
Thành phố Hanoi
Định dạng
Số trang 51
Dung lượng 12,47 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Generating services and Views Once the modules have been uploaded and installed properly, you can start to generate Views.. Services result showing data structure returned from a ViewLea

Trang 1

In this chapter, I am going to cover the building of the jobs board for the RMX, ing with setting up the Drupal side and then shifting quickly to building the Flexinterface I will discuss retrieving records from a Drupal data source and displayingthose records in a Flex-powered interface, and end with reviewing how I built theview filters in the Flex interface You’ve already explored some of these concepts, sonow it’s time to put them to practical use But first, Chris Charlton is going to covercontent management and our overall use of Drupal.

start-Content management

To handle the tons of content being populated by hundreds of user groups

world-wide, we need what’s known as a content management system (CMS) A database is

required for scalable content management systems, and MySQL is more than up forthat task, so knowing what database software will house our data, the only choice left

is deciding on the actual CMS

As Hasan discussed in Chapter 12, we selected Drupal as our CMS Flex and Drupalshare a lot in common; they’re both open source frameworks and have very modularways of working with data and objects If one thing can be guaranteed in this book,

if you spend enough time with either of these frameworks, you’ll get hooked

BUILDING THE JOBS BOARD

By Omar Gonzalez

Chapter 13

Trang 2

So what power does this CMS provide? First, all the CRUD is handled for us—create, read, update,delete—allowing us to concentrate on application logic, as opposed to writing create, read, update,and delete code from scratch Since entering and retrieving data for us will be handled by Drupal, weonly need to concern ourselves with how we’re to get that data from Drupal to Flex and back again.This turns out to be easy, using an approach that might be new to you: Flash Remoting If you’ve neverheard of Flash Remoting, don’t be intimidated; it’s just another component we’re adding to the mix.Adobe has a protocol for Flash and Flex, the Action Messaging Format (AMF), that allows the trans-parent transfer of data and objects to or from Flash/Flex The most popular remoting gateways forPHP are WebORB and AMFPHP.

In case you are unfamiliar with AMF gateways, I’ll briefly define them here Usually our front endsneed to communicate to a server or script somehow These AMF gateways allow our server scripts to

be called or accessed directly in our Flex, almost as if they’re ActionScript methods themselves Thereare many tutorials on this topic floating on the Web dedicated to AMFPHP if you feel like getting yourhands dirty If you are already familiar with remoting gateways, when it comes to integration withDrupal, previous AMF experience helps, but you really won’t have to get your hands dirty here All this

is new territory, so details matter, but you may be surprised how far Drupal will get you

Drupal modules

Once you have Drupal installed (as Hasan covered in Chapter 12), you can begin extending it, tomizing it to your needs We mentioned earlier that Drupal was a modular framework, and nothingsays it more than the hundreds of modules available for download on Drupal’s web site There’s every-thing from dumb clocks to sophisticated modules that even require other modules be preinstalled forthem to work

cus-You should understand that Drupal itself has a core with a set of built-in modules that not only trol Drupal, but also allow you to make more modules and even interface with other installed mod-ules The most important module is the Node API Drupal calls practically everything a node Imagine

con-a content node con-as con-a bcon-asic object, con-and con-a complex content node extended from thcon-at bcon-asic node Econ-achnode has a title, body text, and an originating author Anything above that is dealt with in a customcontent node Our content management framework allows us to do things like make new nodes andcustom content types without any hand coding, so I won’t go into detail here about how to createthese types manually If you are interested in a detailed look at the inner workings of Drupal, check

out Pro Drupal Development by John K VanDyk and Matt Westgate (Apress, 2007) and Building Online Communities with Drupal, phpBB, and WordPressby Robert T Douglass, Mike Little, and Jared W.Smith (Apress, 2005)

The RMX runs off dozens of modules (see Figure 13-1), not so much as to offer dozens of features, butbecause some modules work together, and as we mentioned earlier, some modules require othermodules in order to run properly The two modules required for connecting a Flex front end to aDrupal back end are the Services module and the AMFPHP module Another module that’s key is theViews module, which isn’t for counting page views but for generating views more common to whatdatabase people build All those modules are available on Drupal’s web site at no charge

Modules, which are just PHP files with a module file extension, are really simple to install Just uploadthe module file to your Drupal’s sites/all/modules/ directory, and then activate it in the user accessadministration area We’ll be using all three modules I’ve just mentioned (AMFPHP, Services, andViews) for this chapter and the next, so you may want to install them to follow along

Trang 3

Figure 13-1 Drupal modules page

Once you have your modules uploaded, you need to configure a couple of additional settings withinDrupal One key setting is to enable clean URLs; this option activates Apache’s mod_rewrite to clean

up the URLs our application generates Also, Drupal has user access rights that always need to be setfor every module you install Make sure user access is turned on for both the Services module and theViews module You should then see both modules listed in the administration page Now that you’reset up, it’s time to generate some Views and access them through the Services module

Generating services and Views

Once the modules have been uploaded and installed properly, you can start to generate Views Theterm “Views” can mean many things to different developers; as I mentioned previously, databasedevelopers may be familiar with these types of Views A View is an outlook on a set of data Normally,retrieval of data returns a simple set, like a list of users Additional database code is required to join

or filter data from more than one database table, and this is where Views come in handy A preparedView can bring back not only a list of users, but also login stats, multiple permissions, and anythingelse an application would need when retrieving a list of users Another way to look at Views is thatthey’re almost like superqueries since they can call subqueries internally and even alter or format thedata before it is returned

Some neat people released the Views module for Drupal to help everyone generate Views in a webform (see Figure 13-2) and reduce hand coding If you don’t plan to add any custom content typesabove what the core offers—blog posts, forums, pages—you won’t need to generate Views much or

Trang 4

even at all Since we’re using custom content types, we definitely need to generate some Views for theRMX Drupal implementation Browse to the Views module in the Administration area of Drupal.You might have caught the point earlier that the Views module isn’t required for Flex and Drupal com-munication, but trust me when I say it’s insanely handy I’ll stick to my promise and not get your handsdirty The Views we have built require no SQL or PHP coding.

Figure 13-2 Drupal Views start page

Generating Views in Drupal

At first glance, the long form for creating or editing a View can be either quite intimidating or tizing There are many sections to the form, mostly optional, and to complete a View you only need tofill out the Fields,Arguments,Filters, and Sort Criteriasections Depending on your needs, you may noteven need to edit all those sections, and the form tries to be informative, so give each section a read

appe-to determine whether it is required for your needs

Trang 5

The top of the Views form asks for a human-readable and machine-readable name for the View to becreated The machine-readable name is necessary for the testing and ActionScript code in this exam-ple, so be sure to specify one if you are following along.

Be sure to add content for whatever node type you’ll be retrieving from the View; otherwise, you’llhave no fun testing the service and not see any data come back If Drupal is still too new for you, addcontent through the Create contentmenu in your Navigation menu block Once you’re done making aView, it’s time to test it through the Services module

Religious coders may wonder why we used the Views module, as opposed to coding the PHP and SQL

by hand Well, when working with Drupal’s framework, which is technically a content managementframework (CMF), we want to use portions of the framework that work best for us, and when retriev-ing data, a View is the quickest maintainable solution So, unless you planned to get thoroughlyschooled in Drupal standards and programming methods, you’d spend at least a good couple of daysjust reading and learning the terminology We’re here to get you up and running today So, yes, youcan code all this out, but when there’s a good tool for you to use instead, why not use it?

Calling Views through the Services module

I know you’re excited to get your Views module running in your interface, but you need to test theViews through the Services module first The Services module is the gateway; you can use it to sendmessages between PHP and Flex in ActionScript-ready formats Remember, behind the services curtain

is AMFPHP providing the remoting gateway, so you’ll first test to ensure the AMFPHP is set up rectly (see Figure 13-3) When you browse to the Services module’s screen, you’ll see a list of servers(see Figure 13-4); click the AMFPHP - /services/amfphplink to test your gateway If this fails, you mustresolve the issue before proceeding Make sure all the AMFPHP files are uploaded and that the properDrupal modules are installed and activated Your user account should also have permissions to accessthe Drupal modules installed

cor-Figure 13-3 AMFPHP gateway test

Trang 6

Figure 13-4 Drupal Services start page

Under the list of servers you should notice a few lists of services for node, system, taxonomy, user, andViews Obviously, you’ll be using the Views service for that new View you made earlier Clickviews.getView(see Figure 13-4) and enter your machine-readable name for your custom View in theview_namefield of the service testing form To start, you only need to enter the View name (see Figure13-5) and click the Call methodbutton You should then see some data or a data structure come back.Remember, you need to add some content before you head over to Flex, so if you haven’t done thatyet, please do so now Take a screenshot or make a list of the data structure that is returned: these arethe fields to which you’ll be mapping bindings and code

When you’re satisfied with your View being returned through the services test form, it’s time to bustout your front end in Flex

Trang 7

Figure 13-5 Services result showing data structure returned from a View

Learning more about the Drupal Services module

Technically, you can roll any CMF/CMS with AMFPHP or similar, but we’ve chosen Drupal Drupal hasmany handbooks available on its web site, and each module tries to document as much as it can, butremember, the modules are mostly free, so they’re all being developed in people’s spare time Luckily,there are a few tutorials and video recordings of how to install Drupal and modules, and even somebasics of working with the Services module

Even with these helpful videos, it’s important not to get frustrated when you can’t find information orare stuck—you’re not alone The entire array of wiring an AMF gateway into Drupal is new, so therearen’t really any bugs that will hold you up, but the limited documentation can create hurdles TheServices and AMFPHP modules are currently handled by one person, and hopefully this won’t be thecase moving forward And now let’s get back to Omar to build the Flex interface to bring our infor-mation to life

Trang 8

Preparing to start the jobs board

As I underscored in Chapter 4, the first place I start coding any application is by examining what kinds

of data the application will handle, and then map out all the data transfer objects (DTOs) I will need

in development For this particular application, the jobs board, I only need a Job DTO to get tion for a particular job from one part of the application to another However, because the objectsbeing received from Drupal are not objects we formatted ourselves for easy transfer, and because theDrupal objects are big, we need a more robust DTO than the basic DTO I covered earlier in the book

informa-Advanced DTOs

In my first example, of a DTO in Chapter 4, the data object handled by the DTO was rather simple Theobject held one property only In the case of the data objects returned from Drupal to the jobs boardapplication, I first have to parse the data, assigning values within the DTO, to facilitate my work trans-ferring the data

To begin to understand the need for the extra parsing, you must first look at the data object I amreceiving from Drupal This is what one record return would look like for a sample job entry:

Drupal return = (Array)#0[0] (Object)#1

body = "<div class="wiki-content"><p>Lorem ipsum dolor sit amet

Ut purus neque, viverra a, interdum dignissim, nonummySed a massa a augue eleifend vulputate Vivamus tortor quam, eleifend

</p><p>Donec lacinia blandit urna Phasellus sed purus Donec laoreetVestibulum aliquet lorem ac arcu Donec imperdiet metus sed nunc Sednon elit non elit aliquet viverra CSS Nunc ultrices sodales dui

</p><p>Suspendisse leo eros, laoreet condimentum, accumsan elementum

Vestibulum volutpat arcu ut quam Praesent leo ipsum, sodales a, nulla

Sed lacinia varius libero Vivamus tortor felis, rhoncus eget

</p></div>"

body_value = "Lorem ipsum dolor sit amet, consectetuer adipiscing

neque, viverra a, interdum dignissim, nonummy Flash eget, nisi Sedeleifend vulputate Vivamus tortor quam, eleifend et, laoreet faucibus,pede Vestibulum risus Nam pede Praesent ac libero Proin arcu "

value = "Full-time"

field_job_role = (Array)#4[0] (Object)#5

value = "Web Developer/Coder"

[1] (Object)#6value = "RIA Developer"

[2] (Object)#7value = "Video Editor"

Trang 9

[3] (Object)#8value = "Project Manager"

field_location = (Array)#9[0] (Object)#10

value = "On-site"

field_location_zip = (Array)#11[0] (Object)#12

value = "90909"

field_pay_range_max = (Array)#13[0] (Object)#14

value = "200"

field_pay_range_min = (Array)#15[0] (Object)#16

value = "100"

field_payment_contract = (Array)#17[0] (Object)#18

value = "Hourly"

field_seniority = (Array)#19[0] (Object)#20

value = "Mid-Level"

field_source = (Array)#21[0] (Object)#22

value = "From Employer"

files = (Array)#23format = "1"

last_comment_name = (null)last_comment_timestamp = "1184881274"

Trang 10

name = "Adobe Integrated Runtime (AIR)"

tid = "4"

vid = "2"

weight = "-8"

teaser = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit

viverra a, interdum dignissim, nonummy Flash eget, nisi Sed a massavulputate Vivamus tortor quam, eleifend et, laoreet faucibus, euismod

Vestibulum risus Nam pede Praesent ac libero Proin arcu Morbilacus Nullam vulputate, augue suscipit mollis pellentesque, ligulapharetra commodo arcu dolor et ante Duis a eros et magna congue."

title = "the newest job I swear"

{[Bindable]

public class Job extends Object{

Trang 11

public var title:String;

public var description:String;

public var postedBy:String;

public var positionIs:String;

public var jobLocation:String;

public var requiredKnowledge:String;

public var jobRoles:String;

public var seniority:String;

public var payrange:String;

public var minimumPay:Number;

public var maximumPay:Number;

public var location:String;

public var jobSource:String;

public var paymentContract:String;

public function Job(newJob:Object = null){

super();

if (newJob){

parseObject(newJob);

}}private function parseObject(newInfo:Object):void{

var tags:Array = new Array();

for each (tag in newInfo.taxonomy){

if (tag){tags.push(tag.name);

}}requiredKnowledge = tags.toString();

Trang 12

var role:Object;

var roles:Array = new Array();

for each (role in newInfo.field_job_role){

if (role){

roles.push(role.value);

}}jobRoles = roles.toString();

var positionType:Object;

var positions:Array = new Array();

for each (positionType in newInfo.field_employment_status){

positions.push(positionType.value);

}positionIs = positions.toString();

}}}

In this example, the code that assigns values to the DTO’s properties is in its own method calledparseObject, which is mainly to keep the code cleaner and organized The first few lines of themethod look very similar to the ones in Chapter 4, except that in this example I use dot notationinstead of bracket notation to gain access to the properties I want from the Drupal return Some prop-erties like payRange concatenate two of the properties from the Drupal record object, which isanother example of some of the custom logic written to get the data transferred to the display for-matted the way the application requires it in order to be viewed on the display according to the specdocuments

Right after the first block of code, there are three for each loops that populate some of the DTO’sproperties These loops are necessary because the information is returned by Drupal in an arrayobject So, for example, the first for each loop cycles through the members of the taxonomy arrayreturned from Drupal From this array object, the display only needs the name property, so that is whatgets stored

Setting up custom events

To have the application react to certain user inputs, you use events like a mouse click or a rollover.Not only do they let you know that something has happened, but they also carry information that isrelevant to what just occurred within the application In the case of the jobs browser, the List compo-nent that displays each job dispatches an itemClick event Although this event notifies the applicationthat something has been clicked in the jobs list, the native event does not contain very useful infor-mation, such as the details of which event has been clicked This means I need to gain access to iteither through a property on the event or directly through the application

With a custom event, it is possible to add a property of the event that holds the information or objectyou need access to In the example of the jobs browser, the job itself would be included To do this, a

Trang 13

new class must be written that extends the Event class This new class, which extends Event, can haveall the custom properties necessary for a particular event in the application Going back to the jobsboard, the custom event class looks like this:

package com.almerblank.rmx.flex.events{

import flash.events.Event;

import com.almerblank.rmx.flex.dto.Job;

[Event(name="jobSelected",type="com.almerblank.rmx.flex.events.JobsBoardEvent")]

public class JobsBoardEvent extends Event{

public static const JOB_SELECTED:String = "jobSelected";

public var job:Job;

public function JobsBoardEvent(type:String, bubbles:Boolean=false,

cancelable:Boolean=false){

super(type, bubbles, cancelable);

}}}The class is very small, but extremely handy The first line, just before the class declaration but insidethe package, is the event metadata This metadata is there for the Flex compiler so that it can recog-nize the events as MXML tag attributes from within an MXML file It should be above the class so it isbound to the class, and not to a particular member of the class

The next line is a static constant, which is what should be used as the type parameter when creating anew JobsBoardEvent The third line in the class is the job custom property of Job type, which is theDTO for the jobs board This property will be used to transfer data from the jobs list to the rest of theapplication

From the base class for the item renderer of the jobs list, which you can see in Figure 13-6, I assign amouse click event on the root container of the item renderer In this event handler method,jobSelected(), I dispatch the custom event that carries the job DTO in it This code in the item ren-derer looks as follows:

Trang 14

The jobSelected method is an event handler for the mouse click event on the item renderer’s basecontainer In it, a variable e has been initialized, which is my custom event object As the first argu-ment, I use the JOB_SELECTED constant to determine the event type, and then send true in the secondargument, which determines whether the event bubbles or not I want to listen for this event on thebase class of the JobsBoard application, so I set this to true so that it bubbles up If it were omitted,the event would not be heard by the base class of the application It would only be heard locally onthe item renderer object.

Figure 13-6 The jobs browser for the RMX jobs board

Connecting to the Drupal services

The next bit of code to cover is how the Flex front end connects to the AMFPHP Drupal services Thesetup needed for interfacing with the Drupal services requires a few variables in the way that theRemoteObject is set up, so I encapsulated that functionality into a Services class that would be easy

to use and easy to maintain

The next challenge I faced was writing this with minimal documentation The Flex language documents

do not provide examples for using the RemoteObject class in ActionScript, and I could not find manyexamples online, so I had to go through a bit of trial and error to write this class

Trang 15

The class looks something like this:

package com.almerblank.rmx.flex.network{

* The serviceProperties object holds all the properties

* for each remote method

*/

public static const serviceProperties:Object = {

"view_jobs_all" : {'module': 'views', 'method':"getView",'view':'view_jobs_all','fields':null },

"event_date_cc" : {'module': 'views', 'method':"getView",'view':'event_date_cc',

'fields':null }

};

private static var _remoteObj:RemoteObject;

private static var _showBusyCursor:Boolean = true;

/**

*

* @param methodName - the service being called

* @param result - the result handler

* @param fault - the fault handler

* @param arguments - used to pass information to Drupal to process

* @param showBusyCursor - set to false to manage cursor yourself

*

*/

public static function call(methodName:String, result:Function,

fault:Function,

Trang 16

arguments:Array = null,showBusyCursor:Boolean = true):void{

if (!showBusyCursor){

// send service code for getView method

// wrapped in if statement to accomodate for// possibility that the parameters sent in svc.send() method// might change in order

if (serviceProperties[methodName]['method'] == 'getView'){

if (serviceProperties[methodName]['fields'] && arguments){

svc.send(serviceProperties[methodName]['view'],

serviceProperties[methodName]['fields'], arguments);}

else if (serviceProperties[methodName]['fields']){

svc.send(serviceProperties[methodName]['view'],

serviceProperties[methodName]['fields']);

}else{svc.send(serviceProperties[methodName]['view']);

}}}

Trang 17

_remoteObj.showBusyCursor = true;

}}}}There are only two calls within this example of the Services class: one for retrieving a jobs list andone for retrieving events Dissecting this one piece at a time, let’s start with the two constants at thetop of the class These two constants are used to choose which service call in the class you want toaccess, either Services.GET_JOBS or Services.GET_EVENTS These constants work together with theserviceProperties private object, which contains all of the variables needed to make a successfulDrupal AMFPHP service call to the Services module

To actually call a service, I use the only public method in the class, call(), which is actually a publicstatic method I made the class based on a static method so that it is easily invoked from anywhere

in the application code without first instantiating the class, and I do not need multiple object instances

of this functionality for the application This makes the class more convenient and flexible The callmethod expects five arguments, two of which are optional The first argument is the methodName Iwant to call, which I use the predefined constants for The second and third arguments are the resultand fault handlers, in that order The fourth argument defaults to null, which is for any additionalarguments that I want to send to the service The last argument, showBusyCursor, defaults to true sothat it handles the turning on and off of the busy cursor while the call is being made

Within the call method is where the guts of the class exist The first thing I do is make sure thatthe showBusyCursor hasn’t been set to false After that simple check, there is a call to thestartRemoteObject() method This method sets up a basic remote object and assigns the correctvalues to the properties that don’t change when you call different remote methods After that is done,the next two lines set up the first two dynamic properties that change on the RemoteObject instance.The fault event handler passed in to the call method is assigned to the remote object, and thesource attribute is retrieved from the serviceProperties object, using the static const as the arrayindex to grab the values appropriate for the call

The next bit is what I couldn’t find any documentation for, and that is how the <mx:method/> tags getinterpreted into ActionScript The <mx:method/> tags are turned into instances of the Operation class

On the first line, I start a new Operation instance, and pass in the RemoteObject instance so that itstarts the Operation instance On the next line I point the name property to the method to execute

Trang 18

from the serviceProperties object Once that is done, in order to execute the operation, I use thegetOperation method on the RemoteObject instance With another function variable called svc, Iretrieve the Operation instance with the getOperation method using the name I assigned to it afterinstantiation On the svc reference, I add the result event handler that was passed into the call()method of the Services class, which executes whatever logic I need after I get the results from theservice call.

Finally, the last if statement checks which method is being called, and changes the arguments ingly To accommodate for that possibility, the if statement makes sure certain conditions are met tomake the appropriate call, using the svc.send() method This small and handy class saves me timewhen I need to call a service, and centralizes all code dealing with service calls to this one class

accord-The RMX base class

In Chapter 4, I talked about extending the <mx:Application/> tag in order to add the functionality toyour application within that class For this project, there is more than one application, so the class can-not be shared by all the RMX applications However, there are still things that the applications share,

so for this type of project setup, I use an RMX class that extends the Application class This classincludes things like service fault handlers, and it looks something like this:

package com.almerblank.rmx.flex{

import mx.core.Application;

import mx.utils.ObjectUtil;

/**

* The <code>RMX()</code> class is the base that contains

* functionality common to all of

* the RMX This class gets extended to make

* applications such as the jobs board

super();

}/**

* The <code>svcFault(fault)</code> method handles all

* service call errors and

* displays a human readable error display and an

Trang 19

* option to see the technical error

I can include other content shared by the multiple applications in the RMX For example, this could beCSS classes and overall application properties like width and height When I begin work on a newapplication, such as the jobs board, the application class can extend RMX.as

Setting up the jobs browser

To start the jobs board, I add a new package within the views package Inside it is a components age, which holds all of the components that make up the jobs board The project folder structurelooks like what you see in Figure 13-7

pack-Most of the components are simply made up of MXML layouts for the different parts of the jobsboard The job post has two files, JobPost.as, which is the base class for JobPostView.mxml, andJobRenderer.as, which is the base class for JobRendererView.mxml The main application file is in theroot, named JobsBoardView.mxml This MXML file, shown here, initializes the JobsBoard.as class andholds the base functionality of the jobs board application

JobsBoardView.mxml

<?xml version="1.0" encoding="utf-8"?>

<rmx:JobsBoardlayout="vertical" verticalGap="0"

<mx:State id="filterState" name="filterState">

<mx:AddChild relativeTo="{jobsBrowser}" position="before">

<components:JobFilters id="jobFilters"

creationPolicy="all" height="1"/>

Trang 20

<mx:Sequence id="tn" targets="{[jobsBrowser, jobFilters]}">

<mx:Resize duration="600" target="{jobFilters}"

<mx:ViewStack id="vs_jobsBoardViews" width="100%" height="100%">

<mx:VBox width="100%" height="100%" hideEffect="{hideViewWipe}"

Trang 21

Figure 13-7 The project folder structure for the jobs board

The majority of the code in this MXML file is mainly for the state change when the filters come in andthe transitions are used between the filtered View and the nonfiltered View The core of the applica-tion, which starts after the comment under the <mx:Style/> tag, is really two base tags One is a con-trols component that has the menu for the application, Controls.mxml, and the other is a ViewStack,which holds the JobsBrowser component and the JobPost component Since this section is about thejobs browser, let’s explore the JobsBrowser component

Trang 22

<?xml version="1.0" encoding="utf-8"?>

<mx:HBoxhorizontalGap="0"

as the application loads, the jobs are listed in this component This component doesn’t have any baseclass with functionality in it, as you may have guessed because the name does not end with the word

“View”; it is simply a layout MXML file The file looks like this:

<?xml version="1.0" encoding="utf-8"?>

<mx:VBoxverticalGap="0"

xmlns:mx="http://www.adobe.com/2006/mxml"

width="100%" height="100%">

<mx:Label id="tf_listingsCount" styleName="miscInfo"

text="0 Job Listings" height="22"/>

Calling the jobs service

Since these components are all MXML layouts, how is the application started? Let’s take a look at theJobsBoard.as class This class is a bit long, so I’ll start by discussing a little bit of it at a time

package com.almerblank.rmx.flex.views.frontend.jobsboard{

import com.almerblank.flex.controls.Button;

import com.almerblank.rmx.flex.RMX;

import com.almerblank.rmx.flex.dto.Job;

Trang 23

* The JobsBoard class is the base for the jobs board

* application for the RMX This class is instantiated

* in the application file for the jobs board, RMXJobsBoard.mxml

* The JobsBrowser object gets instantiated in MXML, this object

* does not need instantiation within this class

*/

[Bindable] public var jobsBrowser:JobsBrowser;

/**

* The Controls object gets instantiated in MXML, this object

* does not need instantiation within this class

*/

public var controls:Controls;

[Bindable] public var jobFilters:JobFilters;

[Bindable] public var vs_jobsBoardViews:ViewStack;

[Bindable] public var jobDetails:Job = new Job();

Trang 24

public var rolesProviderDP:Array;

[Bindable] public var easeOut:Function = Quadratic.easeOut;

private var _filters:JobFilters;

private var _lastControlsDP:Array;

At the top public variables are declared with the same name as the id values that the MXML tags oftheir object type have in JobsBoardView.mxml For example, the <mx:JobsBrowser/> tag has an id ofjobsBrowser, so there is a public variable in this class called jobsBrowser, which gives me access andcode hinting into that instance of <mx:JobsBrowser/> There are also a few other properties that areused throughout the application, like data providers for job type combo boxes and such Right nowthe first area of interest is the class constructor, which is what gets the ball rolling, so to speak Afterthe super() call, which gets the super class started, I add two event listeners One is for the customevent that is being dispatched by the item renderer, which I talked about briefly earlier in this chapter,and the other event listener is for the creationComplete event on the JobsBoard class The event han-dler for creationComplete, jobsBoardComplete, is where I start the application That method lookslike this:

/**

* The <code>jobsBoardComplete(event)</code> method handles

* the creationComplete event of the application,

* setting up the initial state of the application

Trang 25

contextMenu = ABCMenu.getInstance();

makeDataProviders();

getJobs();

}The first line here adds the event handler for the menu at the top of the jobs board The second line

is a custom contextual menu class that gives the ability to right-click and go forward or back ThemakeDataProviders() method basically makes an array of technologies for the jobs view The last line

is where I make my call to the Drupal services This is what a service call looks like using the customclass from earlier in the chapter:

/**

* The <code>getJobs()</code> method retrieves all jobs from the

* RMX server and sends to the display

Setting up the list view

When the service call receives the result from the server without any errors, the onResult() methodhandles the result The onResult() event handler must expect a single argument of ResultEvent type;the method for the RMX looks as follows:

private function onResult( event:ResultEvent ):void{

jobsDP = new ArrayCollection(

ArrayUtil.toArray( event.result ) );

}

As you can see, it’s another one-line method to handle the Drupal return The result property on theevent is an object, so using the ArrayUtil class, I make an array of it that goes into anArrayCollection to be shown in the list view The jobsDP, however, is a setter, so there is more codethan meets the eye The jobsDP setter looks like this:

/**

* The jobsDP setter sets the data provider for the jobs list

*

* @param jobs The ArrayCollection of jobs to set

* the data provider to

*

*/

public function set jobsDP(jobs:ArrayCollection):void{

Ngày đăng: 14/08/2014, 11:21

TỪ KHÓA LIÊN QUAN