tag:robotlegs.tenderapp.com,2009-10-18:/discussions/questions/721-best-way-for-service-result-dispatch-event-or-update-modelRobotlegs: Discussion 2011-12-31T09:45:17Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/114863002011-11-18T15:45:15Z2011-11-18T15:45:15ZBest way for Service result: dispatch event or update model?<div><p>Hi a.p.,</p>
<ul>
<li>Yes, if you want/need to take a short-cut, you can update your
Model from your Service class, and let the Model dispatch an event
to the rest of your application with the updated data as a payload.
Mediators can listen for that event and pass the data to their
Views. Actors(Models and Services), Mediators and Commands are
communicating with each other through the shared eventDispatcher
provided by the Context. Models and Services can only dispatch
events.</li>
</ul>
<p>In the following example SomeService is updating SomeModel after
receiving the data from an external service. SomeModel dispatches
an event, SomeMediator listens to it and passes the payload to its
view (SomeView)</p>
<pre>
<code>
public class SomeModelEvent extends Event
{
public static const DATA_UPDATED:String="dataUpdated";
public function SomeModelEvent(type:String, someUpdatedData:ArrayCollection, bubbles:Boolean=false, cancelable:Boolean=false)
{
_someUpdatedData=someUpdatedData;
super(type, bubbles, cancelable);
}
protected var _someUpdatedData:ArrayCollection;
override public function clone():Event
{
return new SomeModelEvent(type, someUpdatedData, bubbles, cancelable);
}
public function get someUpdatedData():ArrayCollection
{
return _someUpdatedData;
}
}</code>
</pre>
<pre>
<code>
public class SomeModel extends Actor
{
protected var _someData:ArrayCollection;
public function get someData():ArrayCollection
{
return _someData;
}
public function set someData(value:ArrayCollection):void
{
_someData = value;
dispatch(new SomeModelEvent(SomeModelEvent.DATA_UPDATED, someData));
}
}</code>
</pre>
<pre>
<code>
public class SomeService extends Actor implements ISomeService
{
[Inject]
public var someModel:SomeModel;
private function onDataReceived(someResult:Object):void
{
someModel.someData= someResult;
}
}</code>
</pre>
<pre>
<code>
public class SomeMediator extends Mediator
{
[Inject]
public var view:SomeView;
override public function onRegister():void
{
eventMap.mapListener(eventDispatcher, SomeModelEvent.DATA_UPDATED, onDataUpdated);
}
protected function onDataUpdated(event:SomeModelEvent):void
{
view.setListDataProvider(event.someUpdatedData);
}
}</code>
</pre>
<p>SomeView.mxml</p>
<pre>
<code>
import mx.collections.ArrayCollection;
public function setListDataProvider(dataProvider:ArrayCollection):void
{
someViewList.dataProvider=dataProvider;
}</code>
</pre>
<ul>
<li>Regarding the number of events <strong>my personal
preference</strong> is to have a custom event like this:</li>
</ul>
<p>public class AuthorEvent extends Event<br>
{</p>
<p>public static const AUTHOR_DELETED:String = "authorDeleted";<br>
public static const AUTHOR_SAVED:String = "authorSaved";<br>
public static const AUTHOR_UPDATED:String = "authorUpdated";<br>
...</p>
<p>having different event types for different actions within an
event class for everything related to Author.</p>
<p>or</p>
<p>something more generic, used by different actors:</p>
<p>public class CRUDEvent extends Event //bad name, but it’s
just an example:)<br>
{</p>
<p>public static const ITEM_DELETED:String = "itemDeleted";<br>
public static const ITEM_SAVED:String = "itemSaved";<br>
public static const ITEM_UPDATED:String = "itemUpdated";<br>
...</p>
<p>I hope this helps. Don’t hesitate to ask more questions
:)<br>
Ondina</p></div>Ondina D.F.