Calling CFC Methods from Flash - macromedia COLDFUSION MX 7 Web Application Construction Kit [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

macromedia COLDFUSION MX 7 Web Application Construction Kit [Electronic resources] - نسخه متنی

Ben Forta, Raymond Camden, Leon Chalnick, Angela Buraglia

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید





  • Calling CFC Methods from Flash


    As you have seen, Flash Remoting makes it really easy to create ColdFusion pages that supply information to Flash, or perform whatever other type of processing you want to trigger from movies playing in the Flash Player. Just think of each directory that contains such ColdFusion pages as a service, and of each individual page as a service function.

    Flash Remoting also makes it possible to use ColdFusion Components to supply information or other server-side processing to Flash. Nearly everything you do on the Flash side of things is exactly the same. The only difference is that each CFC constitutes a service, and each of the CFC's methods constitutes service functions.

    In other words, you can think of a service as a collection of functions. Whether you want to write those functions as pages in a directory or as methods of a CFC is up to you.

    Of course, if you go the CFC route, you get all the other benefits of CFCs for free, including automatic documentation and integration with Dreamweaver. But the greatest benefit of going the CFC route is the fact that your CFCs can be used internally by your ColdFusion pages (via the <cfinvoke> tag) or as Web Services, as well as by your Flash applications. See Chapter 22 for details about ColdFusion Components.

    NOTE

    I am talking about ColdFusion Components, special CFML code files executed on the server. ColdFusion Components are completely different from what Flash calls components; the latter show up in the Components panel in Flash and usually present themselves visually within the player.


    I am assuming that you have already read about ColdFusion Components in Chapter 22. If not, you might want to glance at that chapter before continuing here. Or you can just keep reading to get a crash course in CFCs.

    ColdFusion Components as Services


    To demonstrate how easy it is to use ColdFusion Components in your Flash applications, you will now create a CFC that takes the place of the ColdFusion pages used by the Merchandise Browser example in the previous section. The Merchandise Browser calls two ColdFusion pages as service functions: MerchRecordsetProvider.cfm (Listing 26.4) and MerchDetailProvider.cfm (Listing 26.8).

    Listing 26.9 creates a new ColdFusion Component called MerchProviderCFC which can be used instead. The component exposes two methods called MerchRecordsetProvider() and MerchDetailProvider() that correspond to the two ColdFusion pages already in place.

    Listing 26.9. MerchProviderCFC.cfcA CFC That Supplies Data to Flash, ColdFusion, or Other


    <!---
    Filename: MerchProviderCFC.cfc
    Author: Nate Weiss (NMW)
    Purpose:
    Creates a ColdFusion Component that supplies data about products
    --->
    <cfcomponent hint="Provides data about
    merchandise records." output="false">
    <!--- getMerchList() function --->
    <cffunction name="merchRecordsetProvider"
    returnType="query" access="remote"
    hint="Returns a recordset of all products in
    the Merchandise table."
    output="false">
    <cfset var merchQuery = ">
    <!--- Query the database for
    merchandise records --->
    <cfquery name="merchQuery"
    datasource="ows">
    SELECT MerchID, MerchName
    FROM Merchandise
    ORDER BY MerchName
    </cfquery>
    <!--- Return the query --->
    <cfreturn merchQuery>
    </cffunction>
    <!--- merchDetailProvider() function --->
    <cffunction name="merchDetailProvider"
    returnType="query" access="remote"
    hint="Returns details about a particular
    item in the Merchandise table."
    output="false">
    <!--- MerchID argument (required) --->
    <cfargument name="merchID"
    type="numeric" required="Yes"
    hint="The ID number of the
    desired Merchandise record.">
    <cfset var merchQuery = ">
    <!--- Query the database
    for merchandise records --->
    <cfquery name="merchQuery"
    datasource="ows" maxrows="1">
    SELECT MerchID, MerchName,
    MerchDescription, ImageNameSmall, MerchPrice
    FROM Merchandise
    WHERE MerchID = #ARGUMENTS.merchID#
    </cfquery>
    <!--- Format the MerchPrice column in
    the appropriate currency format --->
    <!--- (It's easier to do this with
    ColdFusion than with ActionScript) --->
    <cfset merchQuery.lerchPrice =
    lsCurrencyFormat(merchQuery.MerchPrice)>
    <!--- Return the query --->
    <cfreturn merchQuery>
    </cffunction>
    </cfcomponent>

    Chapter 22 for details.

    If you compare the first <cffunction> block in this listing to the code in Listing 26.4, you will see that it's almost identical. The same query is run to get information about products from the database. The only difference is how the query is returned: instead of returning it specifically to the Flash Player with FLASH.feturn, this code returns it to whatever program is calling the method with the <cfreturn> tag.

    In other words, the two versions of the code are the same, except that the CFC version isn't coded specifically for Flash, which means you get the bonus of being able to use this method internally within your ColdFusion pages. The access="Remote" attribute means the method can also be accessed as a Web Service.

    The same goes for the second <cffunction> block; it's nearly identical to Listing 26.8, the ColdFusion page on which it is based. Instead of expecting a parameter called merchID to be passed from the Flash Player specifically, it simply expects that an argument named merchID be passed to the method, whether it's called by Flash, from a ColdFusion page via the <cfinvoke> tag, or by some other means.

    See Chapter 22 for further discussion of CFC concepts, and for details about <cffunction>, <cfargument>, and <cfreturn>.

    Calling CFC Methods


    Once the CFC in Listing 26.5) and change this line:


    myService = gateway_conn.getService("ows.23", this);

    to this:


    myService = gateway_conn.getService("ows.23.MerchProviderCFC", this);

    That's it! You can now publish or test the movie again, and it will behave in exactly the same way it did before.

    As you can see, to create a service reference to a CFC, you simply refer to the CFC by name (that is, the filename without the .cfc extension). You specify the path to the CFC file's location in exactly the same way as you would with the <cfinvoke> tag, by using dots to separate the folder names in the path (rather than slashes).

    Once you've created the service reference variable, you can call its service functions (that is, the CFC's methods) by calling each function as a method of the variable, just as you did before. So, to call the MerchRecordsetProvider() method of the CFC in Listing 26.9, you can continue using the following line of code:


    myService.MerchRecordsetProvider();

    To call the MerchDetailProvider() method of the CFC and provide the MerchID parameter, you can use this line, which is also unchanged from the original version in Listing 26.5:


    myService.MerchDetailProvider({MerchID:MerchListBox.getValue()});

    Of course, if you were to change the name of this CFC method to getMerchDetails(), say, you would simply change the function call accordingly, like so:


    myService.getMerchDetails({MerchID:MerchListBox.getValue()});

    NOTE

    You would also need to change the name of the event handler that executes when the data is received. Instead of MerchDetailProvider_Result, you would name it getMerchDetails_Result.

    Instantiated CFCs


    Flash Remoting doesn't provide a mechanism for directly accessing components stored in the APPLICATION or SESSION scopes as discussed in Chapter 23. When you call a method as a Flash service function, you are always calling the method statically, not via an instance of the component.

    This doesn't mean you have to rule out the idea of instance-based components in your Flash-based applications entirely, however. Chapter 28, "Online Commerce."

    Chapter 28 from the CD-ROM to the ows/28 folder on your ColdFusion server. If not, please do so now. See Chapter 28 for details on how the ShoppingCart component works internally.

    In other words, the CFC in Listing 26.10 is a wrapper around the session-based instance of the Shopping Cart component. This means ColdFusion pages can use the cart instance, and you can still expose it to Flash via the wrapper component.

    Listing 26.10. CallShoppingCartCFC.cfcUsing a Session-Based CFC Instance


    <cfcomponent output="false">
    <!--- addItem() function --->
    <cffunction name="addItem"
    access="remote" output="false" returnType="void"
    hint="Adds an item to the session's shopping cart.">
    <!--- Required argument: MerchID --->
    <cfargument name="merchID"
    type="numeric" required="Yes">
    <!--- Call the Add() method of the
    ShoppingCart CFC --->
    <cfinvoke component=
    "#SESSION.myShoppingCart#" method="add"
    merchID="#ARGUMENTS.merchID#">
    </cffunction>
    <!--- getItemCount() function --->
    <cffunction name="getItemCount"
    returnType="numeric" access="Remote"
    output="false">
    <cfset var cartContents = ">
    <cfset var getCount = ">
    <!--- Call the List() method of the
    ShoppingCart CFC --->
    <cfinvoke component="#SESSION.
    myShoppingCart#" method="list"
    returnVariable="cartContents">
    <!--- Use Query-of-Queries to get
    the number of items in cart --->
    <cfquery dbtype="query" name="getCount">
    SELECT SUM(Quantity) AS ItemCount
    FROM CartContents
    </cfquery>
    <!--- Return the total number of items to Flash --->
    <cfreturn val(getCount.ItemCount)>
    </cffunction>
    </cfcomponent>

    Figure 26.10). Additionally, the Add To Cart button in the detail view for each product now works as expected (it was not operational in the original version).

    Listing 26.5), except for a small number of additions. The code in the first frame of the new movie is shown in Listing 26.11.

    Listing 26.11. ActionScript Code in the First Frame of MerchBrowserCart.fla


    // Include support for Flash Remoting Components
    #include "NetServices.as"
    // uncomment this line when you want to
    use the NetConnect debugger
    // #include "NetDebug.as"
    // --------------------------------------------------
    // Handlers for user interaction events
    // --------------------------------------------------
    // --------------------------------------------------
    // Application initialization
    // --------------------------------------------------
    if (inited == null)
    {
    // do this code only once
    inited = true;
    // set the default gateway URL
    (this is used only in authoring)
    NetServices.setDefaultGatewayUrl
    ("http://localhost:8501/flashservices/gateway")
    // connect to the gateway
    gateway_conn = NetServices.
    createGatewayConnection();
    // get a reference to a service
    // In this case, the "service"
    is the MerchProviderCFC component
    myService = gateway_conn.getService("ows.26.MerchProviderCFC", this);
    cartService = gateway_conn.getService
    ("ows.26.CallShoppingCartCFC", this);
    // Call the service function that fills
    the ListBox with a list
    // of products (from ColdFusion) for
    the user to browse through
    myService.MerchRecordsetProvider();
    }
    // This function executes when the
    user selects an item in the ListBox
    function MerchListBox_Changed() {
    // If this is the first time an item
    has been selected,
    // go straight to the frame that
    loads the detail information
    if (_currentFrame == 1) {
    gotoAndPlay("EndSlideOut");
    // Otherwise, go to the frame
    that slides the display back in (hides it)
    // When it finishes sliding,
    it will load the detail information
    } else {
    gotoAndPlay("StartSlideOut");
    }
    }
    // This function retrieves the
    detail information about the selected product.
    // It's executed when the last
    frame of the movie is reached
    // (when the detail view has
    finished hiding itself under the product list)
    function getSelectedItemDetails() {
    myService.MerchDetailProvider(
    {MerchID:MerchListBox.getValue()});
    }
    // --------------------------------------------------
    // Handlers for data coming in from server
    // --------------------------------------------------
    function MerchRecordsetProvider_Result(result) {
    // First, remove any existing items from the list box
    MerchListBox.removeAll();
    //DataGlue.bindFormatStrings (MerchListBox, result,
    "#MerchName#", "#MerchID#");
    // For each record in the recordset...
    for (var i = 0; i < result.getLength(); i++) {
    // Use the record variable to refer to
    the current row of recordset
    var record = result.getItemAt(i);
    // Add item to the MerchListBox widget,
    which is like a <SELECT> i269
    MerchListBox.addItem
    (record.MerchName, record.MerchID);
    };
    }
    // This executes when a merchandise
    detail record has been received
    function MerchDetailProvider_Result(result) {
    // The result variable is a recordset
    that contains just one row
    // The detailRecord variable will
    represent the row of data
    var detailRecord = result.getItemAt(0);
    // Display detail information in text boxes
    _root.TitleTextBox.text =
    detailRecord.MerchName;
    _root.DescriptionTextBox.text =
    detailRecord.MerchDescription;
    _root.PriceTextBox.text = "Price: " +
    detailRecord.MerchPrice;
    // If the ImageNameSmall column
    contains an image filename, display it
    if (detailRecord.ImageNameSmall.length > 0) {
    // Load and display the product image
    loadMovie("../images/" + detailRecord.
    ImageNameSmall, _root.ImageMovie);
    // Hide the OWS logo
    OWSLogo._visible = false;
    // If there is no image file for this record,
    display the OWS logo instead
    } else {
    // Unload any product image that
    might already be showing
    unloadMovie(_root.ImageMovie);
    // Make the OWS logo visible
    OWSLogo._visible = true;
    }
    // Now that the information about
    the merchandise has been placed,
    // make the display slide back into view,
    revealing the information
    gotoAndPlay("StartSlideIn");
    }
    // This function updates the Number
    Of Items display for the cart
    function refreshCart() {
    // Use Flash Remoting to get
    the number of items in cart
    // When the number has been
    retrieved, execution will continue
    // in the GetItemCount_Result() function, below
    cartService.GetItemCount();
    };
    // This executes when the number of
    items in the cart is received
    function GetItemCount_Result(result) {
    CartItemCount = "Items: " + result;
    };
    // This executes when a user uses
    the Add To Cart button
    function addSelectedItemToCart() {
    cartService.AddItem(
    {MerchID:MerchListBox.getValue()});
    }
    // This executes after an
    item has been added to the cart
    function AddItem_Result(result) {
    // Show the new number of items in the cart
    refreshCart();
    }
    // Show the number of items in the user's cart now
    refreshCart();
    // Stop here, so animation doesn't
    occur until user selects a product
    stop();

    Near the top of the template, a new Flash Remoting service object is created, called cart Service. This object represents the CallShoppingCartCFC component created in Listing 26.10. This is in addition to the myService object already being used to connect to the MerchProviderCFC component from Listing 26.9. I can call CallShoppingCartCFC methods using cartService; I will continue to call the other methods using myService.

    In addition, several new functions have been added near the bottom of the listing, calledrefreshCart(), GetItemCount_Result(), addSelectedItemToCart(), and AddItem_Result(). Note that refreshCart() is called right away, just before the stop() command.

    Aside from the code in Listing 26.11, the following code has been added to the Add To Cart button in the DetailUI layer:


    on (release) {
    addSelectedItemToCart();
    }

    Finally, the following code has been added to the Shopping Cart button at the upper right corner, in a new layer called CartUI:


    on (release) {
    getURL("../28/StoreCart.cfm");
    }

    When this version of the movie first appears, the refreshCart() function in Figure 26.10), the addSelectedItemToCart() function is called. Within addSelectedItemToCart(), the cartService.AddItem() service method is called, executing the AddItem() CFC method from Chapter 28) by clicking the Shopping Cart button in the upper right corner. This causes the browser to navigate to the StoreCart.cfm page (from Chapter 28), where the user can check out, remove items, update quantities, or continue shopping.

    A neat thing about this application is that it proves that both the Flash player and normal ColdFusion pages can use the same SESSION scope. If you make changes in th260 version of the cart, the Flash movie will reflect them, and vice versa. This is because the Shopping Cart CFC, and thus the THIS scope used internally by the component, is maintained in the SESSION scope.

  • / 281