> > @turbogears.expose(format = "json")
> > def getset(self, tablename, rowid, colname, value = None):
> > table = getattr(model, tablename)
> > row = table.get(int(rowid))
> > if value:
> > setattr(row, colname, value)
> > else:
> > return dict(value = getattr(row, colname))
> >
> > This is better because now the getset method is more generic and can
> > handle all SQLObject's inside the 'model' module. Still, it is a bad
> > solution because
> >
> > 1. The getset() method contains stupid getattr tricks.
> > 2. The getset() method is detached from the InstantTextField
> > class. This makes my InstantTextField hard to reuse.
>
> #1 is, imho, not really stupid. It's a standard and useful part of
> Python. This seems like exactly the way to make such a thing generic.
>
> As for #2, InstantTextField is actually *more* reusable. It can be
> made to implement any kind of behavior, just depending on the
> information sent to the controller and what the controller does with
> it. That's the view of widgets being the "view" layer and not
> incorporating controller logic.
I think that it is less reusable because it can't contain stateful
information. Let's take another example. I have an AutoCompleteField
widget which you use like this:
field = AutoCompleteField(name = "myauto", search_controller =
"dosearch", search_param = "input", result_name = "matches")
@expose(format = "json")
def dosearch(self, input):
return dict(matches = ["foo", "bar"])
The Javascript in the widget calls the dosearch method and displays
the returned matches list. Now I want to generalize the code inside
dosearch, similar to how I generalized InstantTextField, so that it
can be reused. I want a controller that can return autocompletion
results for an arbitrary column in an arbitrary table:
class CompleteController(Controller):
@expose(format = "json")
def complete(self, nr_completes, tablename, colname, input):
table = getattr(model, tablename)
cond = LIKE(getattr(table.q, colname), "%" + input + "%")
rows = table.select(cond)[:int(nr_completes)]
return dict(matches = [getattr(row, colname) for row in rows])
As you can see, this won't work because AutoCompleteField expected its
search_controller method only to take one argument by the name of the
search_param variable. Maybe there is a good way to solve this
problem? One way to solve it is ofcourse how to change how
AutoCompleteField works, but if you have to do that, doesn't it prove
that I'm right?
> > #1 can be solved my having the getset() method inside the
> > InstantTextField class where it belongs. But then the method has to be
> > mounted, and methods can't be mounted inside turbogears widgets. If
> > the widgets had worked more like normal GUI widgets I could have
> > written something like this:
>
> But the web is not a normal GUI. A normal GUI is stateful and the web
> is stateless. I think it's dangerous to develop web apps and
> particularly web components that ignore the fact that the web is
> stateless. In your example below, that InstantTextField (and the
> reference to the database row!) would have to hang around on the
True, I didn't realise that. Then I opened two pages to the same url
and wondered why one page seemed to update the other page in
mysterious ways. :) So developing web apps is different from
developing desktop apps.
--
mvh Björn
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/turbogears
-~----------~----~----~----~------~----~------~--~---