Kilka miesięcy temu wziąłem udział w warsztatach Flex Challenge Academic Tour na których zainteresowało mnie używanie Flex-a jako front end dla aplikacji napisanych w czymś innym. Warsztatowym przykładem było, jak łatwo się domyśleć, PHP jednak mnie zainteresowało użycie railsów. W końcu udało mi się znaleźć trochę więcej czasu i poszukałem materiałów w internecie. Natrafiłem na wpis w blogu Ruby on Rails with Flex i z jego pomocą udało mi się dotknąć rąbka ‘RIA Nirvany’
Zakładamy projekt, instalujemy plugin RubyAMF który wprowadza szczyptę magii…
1 2 3 | rails app cd app script/plugin install http://rubyamf.googlecode.com/svn/tags/current/rubyamf |
Generujemy rusztowanie i dodajemy jedną linijkę do kontrolera by umożliwić przekazywanie danych z RoR ‘na zewnątrz’:
1 2 | script/generate scaffold Photo title:string author:string price:integer rake db:migrate |
1 2 3 4 5 6 7 8 9 10 11 12 13 | class PhotosController < ApplicationController # GET /photos # GET /photos.xml def index @photos = Photo.all respond_to do |format| format.html # index.html.erb format.xml { render :xml => @photos } format.amf { render :amf => @photos } # dodana linijka end end ... end |
Teraz czas na na przygotowanie interfejsu we Fleksie:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCreationComplete(event)"> <mx:Script> <![CDATA[ import mx.events.FlexEvent; import mx.controls.Alert; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.collections.ArrayCollection; import com.unitedmindset.vo.PhotoVO; [Bindable] public var photos:ArrayCollection private function getPhotosList(event:Event=null):void { photoRO.getOperation("index").send(); } private function onIndexResult(event:ResultEvent):void { photos = new ArrayCollection(event.result as Array); } private function onCreationComplete(event:FlexEvent):void { getPhotosList(event); } private function onFault(event:FaultEvent):void { Alert.show(event.fault.faultString,event.fault.name); } ]]> </mx:Script> <!-- remote objects --> <mx:RemoteObject id="photoRO" destination="rubyamf" endpoint="rubyamf/gateway" source="PhotosController" showBusyCursor="true" fault="onFault(event)"> <mx:method name="index" result="onIndexResult(event)"/> </mx:RemoteObject> <!-- design --> <mx:Panel layout="absolute" left="10" right="10" top="10" bottom="10"> <mx:AdvancedDataGrid id="photosDG" designViewDataType="tree" dataProvider="{photos}" left="10" right="10" top="10" bottom="10"> <mx:columns> <mx:AdvancedDataGridColumn headerText="Title" dataField="name"/> <mx:AdvancedDataGridColumn headerText="Author" dataField="author"/> <mx:AdvancedDataGridColumn headerText="Price" dataField="price"/> </mx:columns> </mx:AdvancedDataGrid> </mx:Panel> </mx:Application> |
oraz klasa ‘PhotoVO’ którą umieszczamy w /src/com/unitedmindset/vo/PhotoVO.as:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Skompilowany plik umieszczamy w folderze Public. Na koniec pozostaje nam przygotowanie pliku konfiguracyjnego dla RubyAMF który znajduje się w /config/rubyamf_config.rb:
1 2 3 4 5 6 7 8 9 10 11 12 13 | require 'app/configuration' module RubyAMF module Configuration ClassMappings.ignore_fields = ['created_at','created_on','updated_at','updated_on'] ClassMappings.translate_case = true ClassMappings.assume_types = false ClassMappings.register(:actionscript => 'PhotosVO', :ruby => 'Photo', :type => 'active_record', :attributes => ['id', 'title', 'author', 'price', 'created_at', 'updated_at'] ) ParameterMappings.scaffolding = true end end |
Żeby zobaczyć efekt naszej pracy otwieramy localhost:3000/nazwa_pliku.swf. Oczywiście przykład jest najprostszy z możliwych, ale pokazuje z grubsza jak to wszystko wygląda
Bardzo interesujący post. Bez wątpienia wpadnę jeszcze po więcej ciekawych treści.