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

Ooooops: 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).


(*) 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" <t...@crowdersoftware.com> 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 <andrea.ca...@gmail.com> 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 
For more options, visit this group at 

Reply via email to