독도 광고 모금 캠페인


우리 회사에서는 아예 페이징에 대한 컴포넌트를 만들어서 값을 던질수 있게 했는데 이것도 역시 방법이 되겠네요..

ADN FLEX COOKBOOK에 올라온 내용입니다.

COOKBOOK 가보실려면 여기 로 가보세요.

Paged ArrayCollection

by PeterMolgaard on October 6, 2008 Avg Rating 2.5 (2)   |   Log in to rate post.

Tagged with ActionScript

Problem Summary

ArrayCollection does not support paging

Solution Summary

Adding properties such as "pageSize", "numberOfPages" and "lengthTotal" to the existing ArrayCollection and implementing a filterfunction supporting paging gives a simple pagination addition to the existing ArrayCollection class.

Explanation

Yesterday one of the developers in my company had the need for a PagedArrayCollection. A quick search on Google revealed only this implementation, which turned out to be buggy so I decided to implement one myself.

I designed an interface called IPagedCollection which in combination with an extension of the existing mx.collections.ArrayCollection implementation would do the job.

Only hurdle was the need to override addItemAt and removeItemAt as the autoUpdate doesn’t seem to work when a filterFunction is employed. I will look in to this phenomena, but as for now a call to refresh after inserting or removing does the job nicely.

The code itself is quite simple, I have also created a small demo-application which illustrates the use of the collection.

Live Demo

Download of Sources

**
* Copyright(c) 2008 HelloGroup A/S, some rights reserved.
* Your reuse is governed by the Creative Commons Attribution 3.0 Denmark License
**/
package com.hello.collections
{
    public interface IPagedArrayCollection
    {
        function get currentPage() : Number;
        function set currentPage( value:Number ) : void;
        function get numberOfPages() : Number;
        function get pageSize() : Number;
        function set pageSize( value:Number ) : void;
        function get lengthTotal() : Number;
    }
}

/**
* Copyright(c) 2008 HelloGroup A/S, some rights reserved.
* Your reuse is governed by the Creative Commons Attribution 3.0 Denmark License
*
* Known Issues:
* - When the collection changes in size or pagesize, the currentPage is not updated.
*   This is a problem if currentPage is set to a higher value than in the new collection.
**/
package com.hello.collections
{
    import mx.collections.ArrayCollection;
    import mx.events.CollectionEvent;

    public class PagedArrayCollection extends ArrayCollection implements IPagedArrayCollection
    {
        private var _currentPage:Number = 1;
        private var _numberOfPages:Number = 1;
        private var _pageSize:Number = 10;
        
        public function PagedArrayCollection( source:Array=null )
        {
            super( source );
            filterFunction = filterData;
            addEventListener( CollectionEvent.COLLECTION_CHANGE, onChange );
        }  

        /**
        * Adds an item to the collection at the specified index.
        *
        * @param item Item to be added
        * @param index Index of the item to be added
        *
        * Note: Needs to be overridden in order to trigger refresh.
        *        AddItem eventually calls this function so its not needed to override addItem
        **/
        override public function addItemAt( item:Object, index:int ) : void
        {
            super.addItemAt( item, index );
            refresh();
        }

        /**
        * Removes the item from the collection at the specified index
        *
        * @param index Index of the item to be removed
        * @return The item removed
        *
        * Note: Needs to be overridden in order to trigger refresh
        **/
        override public function removeItemAt( index:int ) : Object
        {
            var removedItem:Object = super.removeItemAt( index );
            refresh();
            return removedItem;
        }

        protected function onChange( event:CollectionEvent ) : void
        {
            if( _numberOfPages != numberOfPages )
            {
                _numberOfPages = numberOfPages;
                onPagingChange( PagedCollectionEventKind.NUMBEROFPAGES_CHANGE );
            }
        }
        
        protected function onPagingChange( kind:String ) : void
        {
            dispatchEvent( new CollectionEvent( CollectionEvent.COLLECTION_CHANGE, false, false, kind ) );
        }  

        [ChangeEvent("collectionChange")]
        public function get currentPage() : Number
        {
            return _currentPage;
        }
        
        public function set currentPage( value:Number ) : void
        {
            _currentPage = value;
            refresh();
            onPagingChange( PagedCollectionEventKind.CURRENTPAGE_CHANGE );
        }

        [ChangeEvent("collectionChange")]
        public function get numberOfPages() : Number
        {
            var result:Number = source.length / pageSize;
            result = Math.ceil( result );
            return result;
        }
        
        [ChangeEvent("collectionChange")]
        public function get pageSize() : Number
        {
            return _pageSize;
        }
        
        public function set pageSize( value:Number ) : void
        {
            _pageSize = value;
            refresh();
            onPagingChange( PagedCollectionEventKind.PAGESIZE_CHANGE );
        }

        [ChangeEvent("collectionChange")]
        public function get lengthTotal() : Number
        {
            return source.length;
        }

        private function filterData( item:Object ) : Boolean
        {
            var dataWindowCeiling:Number = pageSize * currentPage;
            var dataWindowFloor:Number = dataWindowCeiling - pageSize;
            
            var itemIndex:Number = getItemIndex( item );
            var result:Boolean = dataWindowFloor <= itemIndex && itemIndex < dataWindowCeiling;
            
            return result;
        }
    }
}

/**
* Copyright(c) 2008 HelloGroup A/S, some rights reserved.
* Your reuse is governed by the Creative Commons Attribution 3.0 Denmark License
**/
package com.hello.collections
{
    public class PagedCollectionEventKind
    {
        public static const CURRENTPAGE_CHANGE:String = "currentPageChange";
        public static const PAGESIZE_CHANGE:String = "pageSizeChange";
        public static const NUMBEROFPAGES_CHANGE:String = "numberOfPagesChange";
    }
}


This is the small demo-application which illustrates and validates that the collection works.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="vertical"
    initialize="onInitialize(event)"
    creationComplete="onCreationComplete(event)">

    <mx:HBox width="100%">
        <mx:Label text="Key:" />
        <mx:TextInput id="keyInput" text="NEW KEY" />
        <mx:Label text="Value:" />
        <mx:TextInput id="valueInput" text="NEW VALUE" />
        <mx:Button id="addButton" label="Add Item" />
        <mx:Button id="removeButton" label="Remove Item" enabled="{ grid.selectedItem != null }" />
        <mx:Label text="Set PageSize:" />
        <mx:ComboBox id="pageSizeSelector" dataProvider="{ [ 5, 10, 25] }" selectedIndex="1" change="{ collection.pageSize = Number( pageSizeSelector.value ) }" />
    </mx:HBox>
    
    <mx:DataGrid id="grid" dataProvider="{ collection }" width="100%" height="100%" />
    
    <mx:HBox>
        <mx:Label text="Count: { collection.length } ({ collection.lengthTotal })" />
        <mx:Label text="( { collection.currentPage }/{ collection.numberOfPages } )" />
        <mx:Label text="PageSize: { collection.pageSize }" />
        <mx:Button label="Previous" enabled="{ collection.currentPage > 1 }" click="{ collection.currentPage-- }" />
        <mx:Button label="Next" enabled="{ collection.numberOfPages > collection.currentPage }" click="{ collection.currentPage++ }" />
    </mx:HBox>  

    <mx:Script>
    <![CDATA[
    
    import mx.events.CollectionEvent;
    import mx.events.FlexEvent;
    import com.hello.collections.PagedArrayCollection;

    [Bindable]
    private var collection:PagedArrayCollection;
    
    private function onInitialize( event:FlexEvent ) : void
    {
        var collection:Array = new Array();
        for( var i:Number = 1; i <= 20; i++ )
        {
            collection.push( { key:"Item_Key_"+ i, value:"Item_Value_"+ i } );
        }
        this.collection = new PagedArrayCollection( collection );
        this.collection.addEventListener( CollectionEvent.COLLECTION_CHANGE, onItemsChange );
        this.collection.refresh();
    }
        
    private function onCreationComplete( event:FlexEvent ) : void
    {
        addButton.addEventListener( MouseEvent.CLICK, addButton_Click );
        removeButton.addEventListener( MouseEvent.CLICK, removeButton_Click );
    }

    private function addButton_Click( event:MouseEvent ) : void
    {
        collection.addItem( { key:keyInput.text, value:valueInput.text } );
    }

    private function removeButton_Click( event:MouseEvent ) : void
    {
        collection.removeItemAt( collection.getItemIndex( grid.selectedItem ) );
    }

    private function onItemsChange( event:CollectionEvent ) : void
    {
        trace( event.kind +" collectionchanged" );
    }

    ]]>
    </mx:Script>
    
</mx:Application>

Posted by 이현호
,
출처 : adobe devnet

Creating BlazeDS channels at runtime

by SujitG on July 10, 2008 Avg Rating 5.0 (1)   |   Log in to rate post.

Tagged with dynamic channels , flex and blazeds , Flex and other technologies , runtime channels

Problem Summary

Usually we create channels in services-config.xml and give URL to channel end points in the same file. In services-config.xml {server.name} and {server.port} tokens are evaluated at runtime, but the {context.root} is not evaluated at runtime. If we have to change the URL along with the web application context root, then we have to re-compile Flex application.

Solution Summary

Solution is simple you will have to create channels on runtime. This is very straight forward and easy. You need not even add your services-config.xml to the compiler arguments.

Explanation

Usually we create channels in services-config.xml and give URL to channel end points in the same file. {server.name} and {server.port} tokens are evaluated at runtime, that is these tokens are replaced based on the URL you are using to access the application. But the {context.root} is not evaluated at runtime. If we have to change the URL along with the web application context root, then we have to re-compile Flex application. It will be great if you can change the end point URL at one location and the Flex application will start using that URL without a need for recompiling the application.

I created a very simple sample application which will access a XML file and then create the channels based on the settings in the configuration file.

XML configurations file with channel details

I created a XML file which has details of the channels which my application has to create. If you see the snippet extracted from the XML file it has definition for AMF channel. In the definition the id is the ID of the channel configured in the services-config.xml file on the server and the endpoint node has the URL to the end point.

Download XML from this URL: ChannelsConfiguration.xml
 
<ChannelsConfig>
<channels>
<channel id=”my-amf”>
<type>amf</type>
<endpoint>http://localhost:9191/lcdssamples/messagebroker/amf</endpoint>
</channel>
</channels>
</ChannelsConfig>
 
Creating Flex application
 
Download MXML file from this URL: DynamicChannels.mxml

Now that I have a XML file with details of the channel my application will be using. I loaded this file when my application starts and create required channels so that my application can communicate with the server for using Remoting/Messaging/Proxy/Data management services provided by LCDS/BlazeDS.

Once the application is created function named loadConfiguration() is invoked which will make a HTTP Service request to get the XML file. Check out the function, it is pretty straightforward HTTP Service call.

When the XML is retrieved I parse the XML file and create channels in the parseConfigurationFile() function. Below are few statements extracted from the parseConfigurationFile() function which are worth explaining

First I create a new channel.
 
_amfChannel = new AMFChannel(channel.@id, channel.endpoint);
 
Next add this channel to the ChannelSet.
 
amfChannelSet = new ChannelSet();
amfChannelSet.addChannel(_amfChannel);
 
That’s it we have created the channel sets which we will be using in the RemoteObject call later. I created more channels

Now that I have the channel sets I need to instruct my RemoteObject to use this channel sets when it is trying to communicate with the server. This is how you do it.

<mx:RemoteObject id=”rmObj” destination=”MySessionHandler”
channelSet=”{amfChannelSet}”
result=”resultHandler(event)”
fault=”faultHandler(event)”
showBusyCursor=”true”/>
 
That is all you need to do. You can invoke operations on RemoteObject as usual. This applies to RemoteObject/Consumer/Producer/DataService
Posted by 이현호
,
결론은 Shared Object를 이용한 Cookie 클래스를 소개하는 겁니다.

--> Jump to Blog <--

필요하다면 한번 봐보시길...
Posted by 이현호
,
오늘도 flex.org 를 통한 DZone 에 올라온 글입니다.

전 개발자/프로그래머 이지 디자이너 출신이 아닙니다만

오늘의 내용에서 추천되는 책들은 플렉스를 하는 사람이라면

한번쯤 보면 좋을거 같다는 생각입니다. 사실 보고 많이 디자인

감각을 높일수 있다면 무지하게 좋겠습니다. ㅠ.ㅠ 워낙에 감각이 떨어지는 지라.. ㅡ.ㅡ;;

--> 10 Books You Must Have in Your Library as a Flash Platform Designer  <--

현재 내가 갖고 있는 것도 있을지 한번 둘러보시기 바랍니다.
Posted by 이현호
,

에.... 도데체 Flex는 어떻게 메모리 할당이 되길래 언제나 메모리 이슈가
나는 걸까요? Java나 C/C++ 특히 시스템 프로그래밍을 하신분들은 처음
Flex나 Flash를 접하면 황당해 하는 부분입니다. ^^;;

뭐 돌아가는 사정을 알게되면 이해가 되면서도 한편으로는 참 난감할때도
있습니다.

--> Profiling Flex Applications in Flex Builder 3 Pro <--

많이 회자되곤 하지만 새로이 배우시는 분들은 많기 때문에 퍼왔습니다.

한번 가벼운(?) 마음으로 읽어보시기 바랍니다.

Posted by 이현호
,