[Proto-Scripty] Re: Tying an Element and a custom class together

2009-10-22 Thread Matt Foster

Yeah that'd be great functionality to allow for a much simpler proxy



On Oct 19, 9:48 am, Eric  wrote:
> Matt,
>
> I like your way of doing it, but my concern is that the documented
> toElement() method seems to be only half implemented.
> A minor change to the $() function could make it work completely (see
> it here:http://pastie.org/660553).
>
> What do you guys think about this change?
>
> Eric
>
> On Oct 17, 12:11 am, Matt Foster  wrote:
>
> > Quick and dirty, im sure there are errors but conceptually this would
> > be my approach...
>
> > var ElementProxy = Class.create({
> >                         initialize : function(ele){
> >                                 this.element = $(ele);
> >                                 this.nodeType = this.element.nodeType;
> >                                 this.tagName = this.element.tagName;
> >                                 this.delegateMethods();
> >                         },
> >                         delegateMethods : function(){
> >                                 var methods = Element.Methods;
> >                                 for(var method in methods){
> >                                         var __method = methods[method];
> >                                         if (Object.isFunction(__method) && 
> > !(__method in this))
> >                                                 this.assignMethod(method, 
> > __method);
> >                                 }
> >                         },
> >                         assignMethod : function(method, __method){
> >                                 this[method] = function(){ return 
> > __method.apply(this.element,
> > [this.element].concat($A(arguments))); };
> >                         }
> >                 });
>
> > --
>
> >http://positionabsolute.net
>
> > On Oct 16, 3:01 pm, Matt Foster  wrote:
>
> > > The "has a" relationship is the only way to go for sure.
>
> > > You could create an ElementProxy class that inherits all the Element
> > > methods but just keeps a reference to the actual DOM reference
> > > internally. All of the Element.Methods are parameterized so I'm sure
> > > there'd be an easy way to delegate the reference.  As long as the
> > > ElementProxy class implements all the regular methods then core
> > > prototype processes wouldn't know the difference between the two.
>
> > > --
>
> > >http://positionabsolute.net
>
> > > On Oct 16, 12:02 pm, Eric  wrote:
>
> > > > Hi,
>
> > > > While I agree with T.J. arguments, there are cases when it is nice to
> > > > have this behavior (DOM element and "Plain object" in the same
> > > > object). On of those case is, for example when you're creating a new
> > > > control class.
>
> > > > The way I do it is:
> > > > - building the DOM element in the class's constructor (and keeping it
> > > > in an attribute) (*)
> > > > - implement the toElement() method in the class (to return this DOM
> > > > element) (*)
>
> > > > The second step allows you to provide your class instance to any
> > > > prototype method instead of a DOM element.
> > > > A small example:http://jsbin.com/omaza
>
> > > > Ops: Previous sentence was wrong... After trying to write the
> > > > example, and checking in the source, it seems that you can only use
> > > > this kind of object as a DOM element in a handfull of prototype's
> > > > methods (insert, update and replace)...
>
> > > > Is it any reason why this behavior is not implemented in $() (this
> > > > would actually allow to use a custom class everywhere where a DOM
> > > > element is needed, and just add one line of code).
>
> > > > Eric
>
> > > > (*) This was the simplest way to explain the process, but you may
> > > > prefer dynamically create the DOM element on the first call of
> > > > toElement() for better efficiency.
> > > > On Sep 10, 10:56 am, "T.J. Crowder"  wrote:
>
> > > > > Hi Andrea,
>
> > > > > FWIW, I'd say the best practice is:  Don't do that, it conflates the
> > > > > model with the view *and* the controller. :-)  (MVC is not by any
> > > > > means the only game in town, but the terminology is useful for
> > > > > questions like this.)  If you ever want to present the business object
> > > > > in two different ways in two different panels (in a list, for
> > > > > instance, and in a details pane that shows the details of the
> > > > > highlighted object in the list), you can't, or rather the code gets
> > > > > ugly fast.
>
> > > > > Instead, I'd suggest keeping the business object separate from the
> > > > > element and using a "has a" rather than an "is a" relationship.  You
> > > > > can do that by storing the business object ID on the element in some
> > > > > way ("data-key" is the attribute I usually use for this, and fits with
> > > > > the proposed HTML5 data attributes standard), either directly or via a
> > > > > small controller.
>
> > > > > The business object should never update the element directly, and so
> > > > > it doesn't need to know about it.  Instead, it should raise event

[Proto-Scripty] Re: Tying an Element and a custom class together

2009-10-19 Thread Eric

Matt,

I like your way of doing it, but my concern is that the documented
toElement() method seems to be only half implemented.
A minor change to the $() function could make it work completely (see
it here: http://pastie.org/660553 ).

What do you guys think about this change?

Eric

On Oct 17, 12:11 am, Matt Foster  wrote:
> Quick and dirty, im sure there are errors but conceptually this would
> be my approach...
>
> var ElementProxy = Class.create({
>                         initialize : function(ele){
>                                 this.element = $(ele);
>                                 this.nodeType = this.element.nodeType;
>                                 this.tagName = this.element.tagName;
>                                 this.delegateMethods();
>                         },
>                         delegateMethods : function(){
>                                 var methods = Element.Methods;
>                                 for(var method in methods){
>                                         var __method = methods[method];
>                                         if (Object.isFunction(__method) && 
> !(__method in this))
>                                                 this.assignMethod(method, 
> __method);
>                                 }
>                         },
>                         assignMethod : function(method, __method){
>                                 this[method] = function(){ return 
> __method.apply(this.element,
> [this.element].concat($A(arguments))); };
>                         }
>                 });
>
> --
>
> http://positionabsolute.net
>
> On Oct 16, 3:01 pm, Matt Foster  wrote:
>
> > The "has a" relationship is the only way to go for sure.
>
> > You could create an ElementProxy class that inherits all the Element
> > methods but just keeps a reference to the actual DOM reference
> > internally. All of the Element.Methods are parameterized so I'm sure
> > there'd be an easy way to delegate the reference.  As long as the
> > ElementProxy class implements all the regular methods then core
> > prototype processes wouldn't know the difference between the two.
>
> > --
>
> >http://positionabsolute.net
>
> > On Oct 16, 12:02 pm, Eric  wrote:
>
> > > Hi,
>
> > > While I agree with T.J. arguments, there are cases when it is nice to
> > > have this behavior (DOM element and "Plain object" in the same
> > > object). On of those case is, for example when you're creating a new
> > > control class.
>
> > > The way I do it is:
> > > - building the DOM element in the class's constructor (and keeping it
> > > in an attribute) (*)
> > > - implement the toElement() method in the class (to return this DOM
> > > element) (*)
>
> > > The second step allows you to provide your class instance to any
> > > prototype method instead of a DOM element.
> > > A small example:http://jsbin.com/omaza
>
> > > Ops: Previous sentence was wrong... After trying to write the
> > > example, and checking in the source, it seems that you can only use
> > > this kind of object as a DOM element in a handfull of prototype's
> > > methods (insert, update and replace)...
>
> > > Is it any reason why this behavior is not implemented in $() (this
> > > would actually allow to use a custom class everywhere where a DOM
> > > element is needed, and just add one line of code).
>
> > > Eric
>
> > > (*) This was the simplest way to explain the process, but you may
> > > prefer dynamically create the DOM element on the first call of
> > > toElement() for better efficiency.
> > > On Sep 10, 10:56 am, "T.J. Crowder"  wrote:
>
> > > > Hi Andrea,
>
> > > > FWIW, I'd say the best practice is:  Don't do that, it conflates the
> > > > model with the view *and* the controller. :-)  (MVC is not by any
> > > > means the only game in town, but the terminology is useful for
> > > > questions like this.)  If you ever want to present the business object
> > > > in two different ways in two different panels (in a list, for
> > > > instance, and in a details pane that shows the details of the
> > > > highlighted object in the list), you can't, or rather the code gets
> > > > ugly fast.
>
> > > > Instead, I'd suggest keeping the business object separate from the
> > > > element and using a "has a" rather than an "is a" relationship.  You
> > > > can do that by storing the business object ID on the element in some
> > > > way ("data-key" is the attribute I usually use for this, and fits with
> > > > the proposed HTML5 data attributes standard), either directly or via a
> > > > small controller.
>
> > > > The business object should never update the element directly, and so
> > > > it doesn't need to know about it.  Instead, it should raise events
> > > > that controllers can respond to by updating the elements they
> > > > control.  When I say "fire event," I'm not necessarily talking
> > > > browserspeak (I wouldn't use browser events for this), just a minimal
> > > > implementation of the Observer pattern (as a mixin or s

[Proto-Scripty] Re: Tying an Element and a custom class together

2009-10-16 Thread Matt Foster

Quick and dirty, im sure there are errors but conceptually this would
be my approach...

var ElementProxy = Class.create({
initialize : function(ele){
this.element = $(ele);
this.nodeType = this.element.nodeType;
this.tagName = this.element.tagName;
this.delegateMethods();
},
delegateMethods : function(){
var methods = Element.Methods;
for(var method in methods){
var __method = methods[method];
if (Object.isFunction(__method) && 
!(__method in this))
this.assignMethod(method, 
__method);
}
},
assignMethod : function(method, __method){
this[method] = function(){ return 
__method.apply(this.element,
[this.element].concat($A(arguments))); };
}
});

--

http://positionabsolute.net

On Oct 16, 3:01 pm, Matt Foster  wrote:
> The "has a" relationship is the only way to go for sure.
>
> You could create an ElementProxy class that inherits all the Element
> methods but just keeps a reference to the actual DOM reference
> internally. All of the Element.Methods are parameterized so I'm sure
> there'd be an easy way to delegate the reference.  As long as the
> ElementProxy class implements all the regular methods then core
> prototype processes wouldn't know the difference between the two.
>
> --
>
> http://positionabsolute.net
>
> On Oct 16, 12:02 pm, Eric  wrote:
>
> > Hi,
>
> > While I agree with T.J. arguments, there are cases when it is nice to
> > have this behavior (DOM element and "Plain object" in the same
> > object). On of those case is, for example when you're creating a new
> > control class.
>
> > The way I do it is:
> > - building the DOM element in the class's constructor (and keeping it
> > in an attribute) (*)
> > - implement the toElement() method in the class (to return this DOM
> > element) (*)
>
> > The second step allows you to provide your class instance to any
> > prototype method instead of a DOM element.
> > A small example:http://jsbin.com/omaza
>
> > Ops: Previous sentence was wrong... After trying to write the
> > example, and checking in the source, it seems that you can only use
> > this kind of object as a DOM element in a handfull of prototype's
> > methods (insert, update and replace)...
>
> > Is it any reason why this behavior is not implemented in $() (this
> > would actually allow to use a custom class everywhere where a DOM
> > element is needed, and just add one line of code).
>
> > Eric
>
> > (*) This was the simplest way to explain the process, but you may
> > prefer dynamically create the DOM element on the first call of
> > toElement() for better efficiency.
> > On Sep 10, 10:56 am, "T.J. Crowder"  wrote:
>
> > > Hi Andrea,
>
> > > FWIW, I'd say the best practice is:  Don't do that, it conflates the
> > > model with the view *and* the controller. :-)  (MVC is not by any
> > > means the only game in town, but the terminology is useful for
> > > questions like this.)  If you ever want to present the business object
> > > in two different ways in two different panels (in a list, for
> > > instance, and in a details pane that shows the details of the
> > > highlighted object in the list), you can't, or rather the code gets
> > > ugly fast.
>
> > > Instead, I'd suggest keeping the business object separate from the
> > > element and using a "has a" rather than an "is a" relationship.  You
> > > can do that by storing the business object ID on the element in some
> > > way ("data-key" is the attribute I usually use for this, and fits with
> > > the proposed HTML5 data attributes standard), either directly or via a
> > > small controller.
>
> > > The business object should never update the element directly, and so
> > > it doesn't need to know about it.  Instead, it should raise events
> > > that controllers can respond to by updating the elements they
> > > control.  When I say "fire event," I'm not necessarily talking
> > > browserspeak (I wouldn't use browser events for this), just a minimal
> > > implementation of the Observer pattern (as a mixin or similar you can
> > > use for lots of different objects).
>
> > > FWIW, and apologies if I went OT, but I hope I didn't,
> > > --
> > > T.J. Crowder
> > > tj / crowder software / comwww.crowdersoftware.com
>
> > > On Sep 9, 3:02 pm, Andrea Campi  wrote:
>
> > > > Hi,
>
> > > > in my application I need JS objects to represent some "business"
> > > > objects, which are represented on the page by an Element.
> > > > I would like to be able to tie the two together in such a way that I
> > > > can us

[Proto-Scripty] Re: Tying an Element and a custom class together

2009-10-16 Thread Matt Foster

The "has a" relationship is the only way to go for sure.

You could create an ElementProxy class that inherits all the Element
methods but just keeps a reference to the actual DOM reference
internally. All of the Element.Methods are parameterized so I'm sure
there'd be an easy way to delegate the reference.  As long as the
ElementProxy class implements all the regular methods then core
prototype processes wouldn't know the difference between the two.

--

http://positionabsolute.net



On Oct 16, 12:02 pm, Eric  wrote:
> Hi,
>
> While I agree with T.J. arguments, there are cases when it is nice to
> have this behavior (DOM element and "Plain object" in the same
> object). On of those case is, for example when you're creating a new
> control class.
>
> The way I do it is:
> - building the DOM element in the class's constructor (and keeping it
> in an attribute) (*)
> - implement the toElement() method in the class (to return this DOM
> element) (*)
>
> The second step allows you to provide your class instance to any
> prototype method instead of a DOM element.
> A small example:http://jsbin.com/omaza
>
> Ops: Previous sentence was wrong... After trying to write the
> example, and checking in the source, it seems that you can only use
> this kind of object as a DOM element in a handfull of prototype's
> methods (insert, update and replace)...
>
> Is it any reason why this behavior is not implemented in $() (this
> would actually allow to use a custom class everywhere where a DOM
> element is needed, and just add one line of code).
>
> Eric
>
> (*) This was the simplest way to explain the process, but you may
> prefer dynamically create the DOM element on the first call of
> toElement() for better efficiency.
> On Sep 10, 10:56 am, "T.J. Crowder"  wrote:
>
> > Hi Andrea,
>
> > FWIW, I'd say the best practice is:  Don't do that, it conflates the
> > model with the view *and* the controller. :-)  (MVC is not by any
> > means the only game in town, but the terminology is useful for
> > questions like this.)  If you ever want to present the business object
> > in two different ways in two different panels (in a list, for
> > instance, and in a details pane that shows the details of the
> > highlighted object in the list), you can't, or rather the code gets
> > ugly fast.
>
> > Instead, I'd suggest keeping the business object separate from the
> > element and using a "has a" rather than an "is a" relationship.  You
> > can do that by storing the business object ID on the element in some
> > way ("data-key" is the attribute I usually use for this, and fits with
> > the proposed HTML5 data attributes standard), either directly or via a
> > small controller.
>
> > The business object should never update the element directly, and so
> > it doesn't need to know about it.  Instead, it should raise events
> > that controllers can respond to by updating the elements they
> > control.  When I say "fire event," I'm not necessarily talking
> > browserspeak (I wouldn't use browser events for this), just a minimal
> > implementation of the Observer pattern (as a mixin or similar you can
> > use for lots of different objects).
>
> > FWIW, and apologies if I went OT, but I hope I didn't,
> > --
> > T.J. Crowder
> > tj / crowder software / comwww.crowdersoftware.com
>
> > On Sep 9, 3:02 pm, Andrea Campi  wrote:
>
> > > Hi,
>
> > > in my application I need JS objects to represent some "business"
> > > objects, which are represented on the page by an Element.
> > > I would like to be able to tie the two together in such a way that I
> > > can use them interchangeably.
> > > This sounds like it should be a common pattern, so I was wondering
> > > what the best practices are.
>
> > > Example:
>
> > > var Foo = Class.create({
> > >   initialize: function(parent) {
> > >     var element = Object.extend(new Element("div", { 'class': 'foo',
> > > 'id': 'myFoo' }), this);
> > >     parent.insert(element);
> > >   },
>
> > >   bar: function() {
> > >   }
> > >   // more methods
>
> > > };
>
> > > Thanks to Object.extend I can easily call: $('myFoo').bar()
> > > But I cannot do the opposite, for instance:
>
> > > var foo = new Foo();
> > > foo.childElements();
>
> > > Note that it would just work if I could return 'element' (which now
> > > behaves like Foo).
> > > However, I've readhttp://dev.rubyonrails.org/ticket/11481andithas
> > > reasonable objections to letting the constructor return a value.
>
> > > So, what gives? Any suggestion?
>
> > > TIA,
> > >   Andrea
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~--~~~~--

[Proto-Scripty] Re: Tying an Element and a custom class together

2009-10-16 Thread Eric

Hi,

While I agree with T.J. arguments, there are cases when it is nice to
have this behavior (DOM element and "Plain object" in the same
object). On of those case is, for example when you're creating a new
control class.

The way I do it is:
- building the DOM element in the class's constructor (and keeping it
in an attribute) (*)
- implement the toElement() method in the class (to return this DOM
element) (*)

The second step allows you to provide your class instance to any
prototype method instead of a DOM element.
A small example: http://jsbin.com/omaza

Ops: Previous sentence was wrong... After trying to write the
example, and checking in the source, it seems that you can only use
this kind of object as a DOM element in a handfull of prototype's
methods (insert, update and replace)...

Is it any reason why this behavior is not implemented in $() (this
would actually allow to use a custom class everywhere where a DOM
element is needed, and just add one line of code).

Eric

(*) This was the simplest way to explain the process, but you may
prefer dynamically create the DOM element on the first call of
toElement() for better efficiency.
On Sep 10, 10:56 am, "T.J. Crowder"  wrote:
> Hi Andrea,
>
> FWIW, I'd say the best practice is:  Don't do that, it conflates the
> model with the view *and* the controller. :-)  (MVC is not by any
> means the only game in town, but the terminology is useful for
> questions like this.)  If you ever want to present the business object
> in two different ways in two different panels (in a list, for
> instance, and in a details pane that shows the details of the
> highlighted object in the list), you can't, or rather the code gets
> ugly fast.
>
> Instead, I'd suggest keeping the business object separate from the
> element and using a "has a" rather than an "is a" relationship.  You
> can do that by storing the business object ID on the element in some
> way ("data-key" is the attribute I usually use for this, and fits with
> the proposed HTML5 data attributes standard), either directly or via a
> small controller.
>
> The business object should never update the element directly, and so
> it doesn't need to know about it.  Instead, it should raise events
> that controllers can respond to by updating the elements they
> control.  When I say "fire event," I'm not necessarily talking
> browserspeak (I wouldn't use browser events for this), just a minimal
> implementation of the Observer pattern (as a mixin or similar you can
> use for lots of different objects).
>
> FWIW, and apologies if I went OT, but I hope I didn't,
> --
> T.J. Crowder
> tj / crowder software / comwww.crowdersoftware.com
>
> On Sep 9, 3:02 pm, Andrea Campi  wrote:
>
> > Hi,
>
> > in my application I need JS objects to represent some "business"
> > objects, which are represented on the page by an Element.
> > I would like to be able to tie the two together in such a way that I
> > can use them interchangeably.
> > This sounds like it should be a common pattern, so I was wondering
> > what the best practices are.
>
> > Example:
>
> > var Foo = Class.create({
> >   initialize: function(parent) {
> >     var element = Object.extend(new Element("div", { 'class': 'foo',
> > 'id': 'myFoo' }), this);
> >     parent.insert(element);
> >   },
>
> >   bar: function() {
> >   }
> >   // more methods
>
> > };
>
> > Thanks to Object.extend I can easily call: $('myFoo').bar()
> > But I cannot do the opposite, for instance:
>
> > var foo = new Foo();
> > foo.childElements();
>
> > Note that it would just work if I could return 'element' (which now
> > behaves like Foo).
> > However, I've readhttp://dev.rubyonrails.org/ticket/11481andit has
> > reasonable objections to letting the constructor return a value.
>
> > So, what gives? Any suggestion?
>
> > TIA,
> >   Andrea
>
>
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~--~~~~--~~--~--~---



[Proto-Scripty] Re: Tying an Element and a custom class together

2009-09-10 Thread T.J. Crowder

Hi Andrea,

FWIW, I'd say the best practice is:  Don't do that, it conflates the
model with the view *and* the controller. :-)  (MVC is not by any
means the only game in town, but the terminology is useful for
questions like this.)  If you ever want to present the business object
in two different ways in two different panels (in a list, for
instance, and in a details pane that shows the details of the
highlighted object in the list), you can't, or rather the code gets
ugly fast.

Instead, I'd suggest keeping the business object separate from the
element and using a "has a" rather than an "is a" relationship.  You
can do that by storing the business object ID on the element in some
way ("data-key" is the attribute I usually use for this, and fits with
the proposed HTML5 data attributes standard), either directly or via a
small controller.

The business object should never update the element directly, and so
it doesn't need to know about it.  Instead, it should raise events
that controllers can respond to by updating the elements they
control.  When I say "fire event," I'm not necessarily talking
browserspeak (I wouldn't use browser events for this), just a minimal
implementation of the Observer pattern (as a mixin or similar you can
use for lots of different objects).

FWIW, and apologies if I went OT, but I hope I didn't,
--
T.J. Crowder
tj / crowder software / com
www.crowdersoftware.com


On Sep 9, 3:02 pm, Andrea Campi  wrote:
> Hi,
>
> in my application I need JS objects to represent some "business"
> objects, which are represented on the page by an Element.
> I would like to be able to tie the two together in such a way that I
> can use them interchangeably.
> This sounds like it should be a common pattern, so I was wondering
> what the best practices are.
>
> Example:
>
> var Foo = Class.create({
>   initialize: function(parent) {
>     var element = Object.extend(new Element("div", { 'class': 'foo',
> 'id': 'myFoo' }), this);
>     parent.insert(element);
>   },
>
>   bar: function() {
>   }
>   // more methods
>
> };
>
> Thanks to Object.extend I can easily call: $('myFoo').bar()
> But I cannot do the opposite, for instance:
>
> var foo = new Foo();
> foo.childElements();
>
> Note that it would just work if I could return 'element' (which now
> behaves like Foo).
> However, I've readhttp://dev.rubyonrails.org/ticket/11481and it has
> reasonable objections to letting the constructor return a value.
>
> So, what gives? Any suggestion?
>
> TIA,
>   Andrea
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~--~~~~--~~--~--~---