Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

MVC's Views - class defs or just templates? 1

Status
Not open for further replies.

OsakaWebbie

Programmer
Feb 11, 2003
628
0
0
JP
I'm starting to rewrite some code of a big database interface in OOP (my first venture into that world), and I want to do the MVC separation thing if I can get my brain around it. Envisioning models is pretty easy, but I'm not sure about views. When I think about what things in my application would be good in a class, one that comes to mind that I currently do over and over is a particular type of table layout (kinda fancy, with a fair amount of jQuery and configurable columns) - I use the same kind of table with a variety of data, so I was thinking that a class for the table might be good, so that the code to generate it is consolidated in one place. Perhaps I'd have a property for an array of the column names and CSS classes, another property of an array of the data (or perhaps I'd have the controller just pass the instantiated model of the data to it), and methods like render(). But when I look at tutorials that give examples of views, they don't have class definitions at all - they are like templates, with just HTML and hooks for variable data to be inserted.

So if my thinking is sound to imagine a class for building an HTML structure like my fancy table, where would such a class be stored in an MVC architecture?
 
don't get too hung up on the purity of MVC. My normal approach is this

1. work out what entities exist in my structure. often these map nicely to the main db tables.
2. build classes just for those entities.
3. all main entities inherit from a single base class (more on which later).
4. if an entity is a sub-entity then inherit from the main entity.
5. keep one class per file.
6. keep all entity based classes in a sub-directory.
7. keep all templates in a separate directory.
8. don't be purist about using procedural or other code in a template if it makes life neater for you to maintain. Loops are especially important in the templates.
9. (personally I) don't have html elsewhere than template files (with one exception - for bail out error messages)
10. for the glue (i.e. the logic that manages the page flow) I use a despatch class with (usually) a gigantic switch panel that hands off to methods within that class. that way every single page call in my apps is ALWAYS to index.php and i have only one point of entry to worry about.
11. inevitably other helper functions are useful. some I keep procedural as they have no natural need to be in a class. for others I build a class. These I keep in a library folder.
12. the base class is, for me, the most important. it handles all the save, update, insert, delete, select etc etc functions necessary for each entity.
13. each entity class contains a model of the data structure.

i will post back with an example model and base class a bit later today, if that would be useful.

to your explicit query, yes I would build a table rendering class. I did one a year or so ago which renders tables for use with a jquery data viewer. i can post that too, if useful.
 
Thanks - that helps a lot. I won't be able to do #10 for a while - this is a mature, complex app, so it would probably take me a year of doing nothing else in order to rewrite it completely in OOP/MVC. I don't have that kind of time - there is a lot more going on in my life. So as I have learned more, I've decided that when I need to work on my existing pages for other reasons, I'll try to start building some of the pieces in OOP - hopefully if I structure them right, they can become part of the future MVC version of the monolith. The key is having enough vision to do them in such a way that they will fit into the future structure, so I don't have to redo them again (much!).

I'm encouraged by your comments that I don't need to be "hung up on..." or a "purist". Back in the days of the move to markup/CSS separation, table allergy, and the "everything must validate" mantra, I had a lot of trouble keeping up, and still do - although I try to be the purist that the world tells me to be, in many cases I spend 100 times as much time getting my layout to behave using CSS than it would have taken to whip up a quick table to hold some things in place. And after I spent a ton of time adding all kinds of things to my markup (e.g. "<br>" -> "<br />") to validate as XHTML, which was supposed to be the new standard, now with HTML5 I'm told that it doesn't matter anymore - argh. Anyway, I digress...

Yes, I would love to see examples of your table class (as well as the model and base you offered, although I think I'm closer to grasping those ideas). My tables also use a lot of jQuery - the simplest cases just use it to allow re-ordering (the tablesorter plugin), the medium cases add the capability of CSV export (hide display-only columns and show CSV-only columns, call the table2CSV plugin, then put it all back), and the fanciest cases (several throughout my app, all joining data from multiple database tables) initially hide columns that the user doesn't usually care about (user settings to choose which ones) and then allow them to show/hide columns dynamically (columnmanager and clickmenu plugins). For that last case, I ultimately want to only query data for the visible columns and use AJAX to fill in columns the user shows later, but I can't get the retroactive-column-filling to work for some reason, so right now I just pull in all the data (which can be quite slow!). I'm hoping that in the process of writing a generic PowerTable class and having to think through how my code works, I'll find the problem and get that last aspect to actually work.

Since I have three levels of fancy-ness, I'm trying to decide if that is best as one class that knows from the parameters which features to implement, or a simple class that is then extended twice by other classes. You can't answer that - I have to see which works best in my code.

Regarding models, I think the only key concept I still lack before diving in is how to handle joined data. The books and tutorial videos I've been studying use really simple examples, with each model representing a single db table. But my database is complex and highly normalized, so I'm constantly joining several db tables in different ways to get what I'm going to show my users. Am I supposed to "join" models somehow in my controllers?

Regarding templates (which I guess are synonymous with "views"?), when there are multiple things on a page (including multiple tables), would you structure it as a single template for the page that reaches out to helpers and instantiated model objects as needed, or a controller that assembles the page from multiple templates (e.g. header + form + powertable + another form + another table + footer)?
 
think of a query of joined tables in two ways

1. data integrity.
this means for CUD operations you will need to overload the base update,insert,delete methods to ensure that the joins are also updated, inserted and deleted. this is one of the joys of inheritance and the base class, it makes doing this very easy.

2. retrievals
you could also simply overload the 'loadbyid()' method (in my examples) for the relevant class.

however if the joined table is better expressed as a view (e.g. you might be aggregating several entities to build a report) then it is probably better to treat the view as an entity itself and overload the save and delete functions with a null-action to stop anything going wrong.

I will post my code as a faq later.
 
on your last paragraph, i don't see templates as views. i see them more as the presentation layer to the user, as opposed to a view which is a data presentation to the application layer.

in terms of whether it is better to have each widget as a separate template, or just one template per page, the answer is that it depends on re-usability. if a particular table might get re-used across multiple templates then it is advisable to split it into its own template and call it with an include. before going down this path consider variable scope. sometimes it is better (for scope reasons) to have the html delivered by the entity class (via a template call) so you don't have to worry about variable scope. i try to avoid this but it's inevitably a better solution in some cases.

I'm very anti-tables for anything other than tabular data. but as for the rest of it, optimisation and normalisation can take too long imo. the cost-benefit curve gets skewed and i find that investing in some more powerful metal is often cheaper than the time it would take to increase optimisation... that said, i normalise when i can but not to extremes as i prefer my tables to be readable.

by way of example to the previous post, take an address card. typically this will contain four entities: name and other unique data, 1 or more addresses, 1 or more telephone numbers, 1 or more email addresses. this translates to four classes. however only one of these classes is addressable by the global scope. the address, telephone number and email address classes are handled only internally to the contact class. so the data integrity is maintained programmatically via overloaded methods within the contact class. makes sense? you then also don't need to worry about joins. just create a getAddress (etc) methods. i will use this as an example in the faq.
 
Thanks again - more helpful perspective. I hadn't heard the term "overload" before in this context, but I just now looked it up.

For some reason, database normalization has always come naturally to me (in fact it feels strange to have anything less than fully normalized), but taming CSS layouts does not. I have not used a table for layout in several years, but when my divs start showing up in strange places, the temptation crosses my mind! By the way, normalization to me is about more than just saving a little space - the main purpose in my mind is data integrity and consistency.

I look forward to your FAQ! :)
 
Still looking forward to seeing your examples (in an FAQ or separately). No rush - I just wanted to say that I value your contributions.

Another example of my view/template confusion came to mind as I was in my code fixing some bugs. My application can record and report people's attendance of events - the database tables are naturally named "event" (with the event name, description, start and end dates, and a bit more) and "attendance" (to make the many-many relationship).  On four pages there is a dropdown to select an event: The maintenance page for editing the event's information, the person detail page to add attendance for that person, a batch page to add attendance for multiple people, and the attendance chart page (to choose an event to view). Every time, I want the same things: the populated <select>, a pair of links managed by jQuery that hide/show events that have already ended (to reduce clutter), and a bit of CSS to go with that (since it's only used four places, I don't want to clutter up my main CSS file). Currently I'm using the absolutely horrendous method of repeating the three chunks of code in the four files (please throw only ripe tomatoes - the green ones hurt too much!). I know I could have done better even in procedural style by including a separate file with three functions (the CSS, the jQuery, and the SQL+markup), but the repetition kinda snuck up on me as the application grew.

Okay, now for how it will work in MVC. I know that the event table would be represented by an entity (model) class. Presumably a method in it like getAllEvents() would pass back an object or array with the data. And there would be four templates (or would these be views?) that would do final assembly of their respective pages (maint, person, batch, and attendance chart). But which part of the structure would call getAllEvents() and return the markup for the <select> and related links? And would that same file have two other methods/functions that return the CSS and jQuery? That functionality is related directly to that one database table, so it seems like it would be closely tied to the model (or even methods in the model), but supposedly markup, scripts, and styling don't belong in the model, so I'm not sure where they should be. Like I said, the role of views (and your additional concept of templates) is still not coming together in my brain.
 
so sorry. unfortunately although I was looking forward to a very calm summer, a whole bunch of new clients came out of the woodwork and i've been working dawn to midnight.

i will take some time to read your post properly and reply later.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top