Re: [flexcoders] Re: Observing collections

2008-08-14 Thread Richard Rodseth
Thanks guys.

Can someone explain how ac:Observe (which this is based on) works? i.e. what
triggers the handler call when somethng in the middle of the source binding
expression changes (eg. b in {a.b.c.myCollection}? I don't see any event
handlers, and there's a mysterious execute() method in the parent class
(Observer).

 And would your version below also fire when b changes?

Otherwise, Josh's example works too, but the collection event is the only
trigger.

On Thu, Aug 14, 2008 at 12:12 AM, Dennis van Nooij [EMAIL PROTECTED]wrote:

   try this:

 package com.adobe.ac
 {
 import mx.events.CollectionEvent;
 import mx.collections.ArrayCollection;
 import flash.events.Event;
 import mx.core.Application;
 import mx.core.UIComponent;


 /**
 *
 * monitors Collections and react on reassining of the variable
 * and changes in the collection which are bindable
 *
 */
 public class ObserveCollection extends Observer
 {
 private var _handler : Function;
 private var _source : Object;

 override public function get handler() : Function
 {
 return _handler;
 }

 public function set handler( value : Function ) : void
 {
 _handler = value;
 if( value != null )
 {
 isHandlerInitialized = true;
 if( isHandlerInitialized  isSourceInitialized )
 {
 callHandler();
 }
 }
 }

 override public function get source() : Object
 {
 return _source;
 }

 public function set source( value : Object ) : void
 {
 if (_source != null){


 _source.removeEventListener(CollectionEvent.COLLECTION_CHANGE,collectionChangeHandler);

 }
 _source = value;


 _source.addEventListener(CollectionEvent.COLLECTION_CHANGE,collectionChangeHandler);

 isSourceInitialized = true;

 if( isHandlerInitialized  isSourceInitialized )
 {
 callHandler();
 }
 }

 protected override function callHandler() : void
 {
 try
 {
 handler.call( null, source );
 }
 catch( e : Error )
 {
 delay( e );
 }
 }

 protected override function delay( e : Error ) : void
 {
 UIComponent( Application.application ).callLater( throwException, [
 e ] );
 }

 private function throwException( e : Error ) : void
 {
 throw e;
 }

 private function collectionChangeHandler (event:Event) : void
 {

 callHandler();
 }


 }
 }

 cheers,
 Dennis


 --- In flexcoders@yahoogroups.com flexcoders%40yahoogroups.com, Alex
 Harui [EMAIL PROTECTED] wrote:
 
  Never used Observe, but if it implements IMXMLObject or you subclass and
  do so, then you can use it in MXML
 
 
 
  
 
  From: flexcoders@yahoogroups.com flexcoders%40yahoogroups.com [mailto:
 flexcoders@yahoogroups.com flexcoders%40yahoogroups.com] On
  Behalf Of Richard Rodseth
  Sent: Wednesday, August 13, 2008 4:16 PM
  To: flexcoders@yahoogroups.com flexcoders%40yahoogroups.com
  Subject: [flexcoders] Observing collections
 
 
 
  For some reason I have an aversion to adding event listeners in
  ActionScript, favouring binding expressions and the Observe tag from
  Adobe Consulting. Not sure how rational this is, but there you have it.
  Binding is just so damn elegant.
 
  However, collections are a problem. It seems that so often you want to
  update something if either the collection itself or its contents
  changes, and you don't really care about the details of the change.
 
  I suppose if you're a DataGrid watching its dataprovider you do care and
  can minimize updates, but in many of the use cases I've encountered,
  that's not the case - my observer is going to do something with the
  whole collection (or maybe I've just been lazy about exploiting possible
  optimizations).
 
  Is there anything like the Observe tag that can be instantiated in MXML
  and can trigger a function call on a COLLECTION_CHANGE event?
 

  



Re: [flexcoders] Re: Observing collections

2008-08-14 Thread Richard Rodseth
Oh, I just stepped through Observe, and I guess the standard binding
mechanism calls the source setter again, which calls the handler.

On Thu, Aug 14, 2008 at 6:49 AM, Richard Rodseth [EMAIL PROTECTED] wrote:

 Thanks guys.

 Can someone explain how ac:Observe (which this is based on) works? i.e.
 what triggers the handler call when somethng in the middle of the source
 binding expression changes (eg. b in {a.b.c.myCollection}? I don't see
 any event handlers, and there's a mysterious execute() method in the parent
 class (Observer).

  And would your version below also fire when b changes?

 Otherwise, Josh's example works too, but the collection event is the only
 trigger.


 On Thu, Aug 14, 2008 at 12:12 AM, Dennis van Nooij [EMAIL PROTECTED]wrote:

   try this:

 package com.adobe.ac
 {
 import mx.events.CollectionEvent;
 import mx.collections.ArrayCollection;
 import flash.events.Event;
 import mx.core.Application;
 import mx.core.UIComponent;


 /**
 *
 * monitors Collections and react on reassining of the variable
 * and changes in the collection which are bindable
 *
 */
 public class ObserveCollection extends Observer
 {
 private var _handler : Function;
 private var _source : Object;

 override public function get handler() : Function
 {
 return _handler;
 }

 public function set handler( value : Function ) : void
 {
 _handler = value;
 if( value != null )
 {
 isHandlerInitialized = true;
 if( isHandlerInitialized  isSourceInitialized )
 {
 callHandler();
 }
 }
 }

 override public function get source() : Object
 {
 return _source;
 }

 public function set source( value : Object ) : void
 {
 if (_source != null){


 _source.removeEventListener(CollectionEvent.COLLECTION_CHANGE,collectionChangeHandler);

 }
 _source = value;


 _source.addEventListener(CollectionEvent.COLLECTION_CHANGE,collectionChangeHandler);

 isSourceInitialized = true;

 if( isHandlerInitialized  isSourceInitialized )
 {
 callHandler();
 }
 }

 protected override function callHandler() : void
 {
 try
 {
 handler.call( null, source );
 }
 catch( e : Error )
 {
 delay( e );
 }
 }

 protected override function delay( e : Error ) : void
 {
 UIComponent( Application.application ).callLater( throwException, [
 e ] );
 }

 private function throwException( e : Error ) : void
 {
 throw e;
 }

 private function collectionChangeHandler (event:Event) : void
 {

 callHandler();
 }


 }
 }

 cheers,
 Dennis


 --- In flexcoders@yahoogroups.com flexcoders%40yahoogroups.com, Alex
 Harui [EMAIL PROTECTED] wrote:
 
  Never used Observe, but if it implements IMXMLObject or you subclass and
  do so, then you can use it in MXML
 
 
 
  
 
  From: flexcoders@yahoogroups.com flexcoders%40yahoogroups.com[mailto:
 flexcoders@yahoogroups.com flexcoders%40yahoogroups.com] On
  Behalf Of Richard Rodseth
  Sent: Wednesday, August 13, 2008 4:16 PM
  To: flexcoders@yahoogroups.com flexcoders%40yahoogroups.com
  Subject: [flexcoders] Observing collections
 
 
 
  For some reason I have an aversion to adding event listeners in
  ActionScript, favouring binding expressions and the Observe tag from
  Adobe Consulting. Not sure how rational this is, but there you have it.
  Binding is just so damn elegant.
 
  However, collections are a problem. It seems that so often you want to
  update something if either the collection itself or its contents
  changes, and you don't really care about the details of the change.
 
  I suppose if you're a DataGrid watching its dataprovider you do care and
  can minimize updates, but in many of the use cases I've encountered,
  that's not the case - my observer is going to do something with the
  whole collection (or maybe I've just been lazy about exploiting possible
  optimizations).
 
  Is there anything like the Observe tag that can be instantiated in MXML
  and can trigger a function call on a COLLECTION_CHANGE event?
 

  





Re: [flexcoders] Re: Observing collections

2008-08-14 Thread Daniel Gold
should all be based on property change events, the heart of binding

On Thu, Aug 14, 2008 at 8:55 AM, Richard Rodseth [EMAIL PROTECTED] wrote:

   Oh, I just stepped through Observe, and I guess the standard binding
 mechanism calls the source setter again, which calls the handler.


 On Thu, Aug 14, 2008 at 6:49 AM, Richard Rodseth [EMAIL PROTECTED]wrote:

 Thanks guys.

 Can someone explain how ac:Observe (which this is based on) works? i.e.
 what triggers the handler call when somethng in the middle of the source
 binding expression changes (eg. b in {a.b.c.myCollection}? I don't see
 any event handlers, and there's a mysterious execute() method in the parent
 class (Observer).

  And would your version below also fire when b changes?

 Otherwise, Josh's example works too, but the collection event is the only
 trigger.


 On Thu, Aug 14, 2008 at 12:12 AM, Dennis van Nooij [EMAIL PROTECTED]wrote:

   try this:

 package com.adobe.ac
 {
 import mx.events.CollectionEvent;
 import mx.collections.ArrayCollection;
 import flash.events.Event;
 import mx.core.Application;
 import mx.core.UIComponent;


 /**
 *
 * monitors Collections and react on reassining of the variable
 * and changes in the collection which are bindable
 *
 */
 public class ObserveCollection extends Observer
 {
 private var _handler : Function;
 private var _source : Object;

 override public function get handler() : Function
 {
 return _handler;
 }

 public function set handler( value : Function ) : void
 {
 _handler = value;
 if( value != null )
 {
 isHandlerInitialized = true;
 if( isHandlerInitialized  isSourceInitialized )
 {
 callHandler();
 }
 }
 }

 override public function get source() : Object
 {
 return _source;
 }

 public function set source( value : Object ) : void
 {
 if (_source != null){


 _source.removeEventListener(CollectionEvent.COLLECTION_CHANGE,collectionChangeHandler);

 }
 _source = value;


 _source.addEventListener(CollectionEvent.COLLECTION_CHANGE,collectionChangeHandler);

 isSourceInitialized = true;

 if( isHandlerInitialized  isSourceInitialized )
 {
 callHandler();
 }
 }

 protected override function callHandler() : void
 {
 try
 {
 handler.call( null, source );
 }
 catch( e : Error )
 {
 delay( e );
 }
 }

 protected override function delay( e : Error ) : void
 {
 UIComponent( Application.application ).callLater( throwException, [
 e ] );
 }

 private function throwException( e : Error ) : void
 {
 throw e;
 }

 private function collectionChangeHandler (event:Event) : void
 {

 callHandler();
 }


 }
 }

 cheers,
 Dennis


 --- In flexcoders@yahoogroups.com flexcoders%40yahoogroups.com, Alex
 Harui [EMAIL PROTECTED] wrote:
 
  Never used Observe, but if it implements IMXMLObject or you subclass
 and
  do so, then you can use it in MXML
 
 
 
  
 
  From: flexcoders@yahoogroups.com flexcoders%40yahoogroups.com[mailto:
 flexcoders@yahoogroups.com flexcoders%40yahoogroups.com] On
  Behalf Of Richard Rodseth
  Sent: Wednesday, August 13, 2008 4:16 PM
  To: flexcoders@yahoogroups.com flexcoders%40yahoogroups.com
  Subject: [flexcoders] Observing collections
 
 
 
  For some reason I have an aversion to adding event listeners in
  ActionScript, favouring binding expressions and the Observe tag from
  Adobe Consulting. Not sure how rational this is, but there you have it.
  Binding is just so damn elegant.
 
  However, collections are a problem. It seems that so often you want to
  update something if either the collection itself or its contents
  changes, and you don't really care about the details of the change.
 
  I suppose if you're a DataGrid watching its dataprovider you do care
 and
  can minimize updates, but in many of the use cases I've encountered,
  that's not the case - my observer is going to do something with the
  whole collection (or maybe I've just been lazy about exploiting
 possible
  optimizations).
 
  Is there anything like the Observe tag that can be instantiated in MXML
  and can trigger a function call on a COLLECTION_CHANGE event?
 



  



Re: [flexcoders] Re: Observing collections

2008-08-14 Thread Troy Gilbert
To repeat what someone said earlier, this exact issue is already
addressed quite cleanly by the aforementioned Observe tag (and it's
more advanced version ObserveValue).

I think the Observe/ObserveValue tags are easily useful enough that
their inclusion in BindingUtils (or wherever mx:Binding is kept) would
be an excellent update to the Flex SDK.

Troy.


Re: [flexcoders] Re: Observing collections

2008-08-14 Thread Richard Rodseth
Not sure I understand what you're responding to.

I agree about the usefulness of the tags.

I don't believe either of them would call a function when the contents of a
collection changes (as opposed to the collection itself). The modification
Dennis offered would.

On Thu, Aug 14, 2008 at 10:37 AM, Troy Gilbert [EMAIL PROTECTED]wrote:

   To repeat what someone said earlier, this exact issue is already
 addressed quite cleanly by the aforementioned Observe tag (and it's
 more advanced version ObserveValue).

 I think the Observe/ObserveValue tags are easily useful enough that
 their inclusion in BindingUtils (or wherever mx:Binding is kept) would
 be an excellent update to the Flex SDK.

 Troy.
  



Re: [flexcoders] Re: Observing collections

2008-08-14 Thread Troy Gilbert
 I don't believe either of them would call a function when the contents of a
 collection changes (as opposed to the collection itself). The modification
 Dennis offered would.

Sorry, completely missed the point, didn't I? ;-) You're right, what
you're looking for would be useful as well! ;-) I'll have to take a
look at Dennis' code.

Troy.


Re: [flexcoders] Re: Observing collections

2008-08-14 Thread Richard Rodseth
No problem. I'm glad someone else thinks it might be useful. I could even
imagine a variation that had multiple handlers, or passed the event to the
handler.

I'm fascinated by what makes sense declaratively, and what doesn't. Flex is
a great playground for the two styles.

On Thu, Aug 14, 2008 at 10:51 AM, Troy Gilbert [EMAIL PROTECTED]wrote:

I don't believe either of them would call a function when the contents
 of a
  collection changes (as opposed to the collection itself). The
 modification
  Dennis offered would.

 Sorry, completely missed the point, didn't I? ;-) You're right, what
 you're looking for would be useful as well! ;-) I'll have to take a
 look at Dennis' code.

 Troy.
  



Re: [flexcoders] Re: Observing collections

2008-08-14 Thread Troy Gilbert
 I'm fascinated by what makes sense declaratively, and what doesn't. Flex is
 a great playground for the two styles.

That's exactly why I (and likely you) found the AS3-based event
handler method distasteful (from your original post): you're forced to
do something best expressed declaratively in the imperative language.
I'd like to see Flex become even stricter in this distinction:

- MXML is declarative and best represents *structure*.
- AS3 is imperative and best represents *behavior*.
- CSS best represents *styling*.

The closer we can get to not being forced to muddy the 3 the better
our code will be. This thread touches on a big place where I often
have to muddy MXML and AS3 (view elements reacting to nested and/or
complex model changes).

While I'm on the subject (though it's unrelated to this thread), I'd
love to see Flex really beef up the CSS, allowing for things like
applying multiple styles to a single component (e.g. style=redBox
bigFont instead of just styleName=redBoxWithBigFont), style
shorthands (e.g. padding: 1 2 3 4 instead of paddingTop: 1
paddingRight: 2, etc...), and making more layout properties stylable
(width, height, x, y, left, right, etc.).

Troy.


Re: [flexcoders] Re: Observing collections

2008-08-13 Thread Richard Rodseth
As far as I recall mx:Binding just invokes a setter (for the destination
property) and I'm pretty sure it doesn't watch CollectionChanged either.

On Wed, Aug 13, 2008 at 8:42 PM, Amy [EMAIL PROTECTED] wrote:

   --- In flexcoders@yahoogroups.com flexcoders%40yahoogroups.com,
 Richard Rodseth [EMAIL PROTECTED]
 wrote:

 
  A little more context. I'm working on a view that builds itself
 dynamically
  (adding children to various containers) based on a description.
 
  So suppose my view has a property called description which has a
 property
  things that is the collection or array.
 
  It's no great hardship to add a listener in the setter for
 description, but
  I wish I could say something like:
 
  mx:WatchCollection source={description.things}
 handler=thingsChanged/

 Have you tried the Binding tag?

 The first time I ever saw it in action was in this file:

 http://examples.adobe.com/flex2/inproduct/sdk/photoviewer/PhotoViewer.
 html

 HTH;

 Amy