Architecture in a JMVC World

(This is a post I put on the JMVC google group. I include it here in case anyone that reads it has any thoughts and so that I can refer to it myself. If you're smart about this sort of stuff, I'm sure the people at the group would like you to increase their knowledge in the context of the post over there.)

I now have a demo app running and have used many features of JavascriptMVC. I am able to operate the tool in a rudimentary way. Now I am starting to figure out how to do things that I know I will want to do in the future. First among these is global navigation but I am very unsure how JMVC wants me to do it. It occurs to me that this might be something that is interesting to others and I sure could use some advice.

I want to have a set of controls of some sort that, when clicked, each provide a different work context. Think, Page A supports Data Entry, Page B supports Reporting and Analysis. Each wants to have completely separate functions. I think that the basic organization is that I want to have a document controller, call it the AppOvervallController and, then I want to have PageAController, PageBController, etc.

Given this, I would have the global navigation receive a click (though this is mysteriously failing right now) and tell the current page controller to clean up and die, and then tell the newly clicked controller to hop into action. Presumably, that controller would need to have some number of application elements that do things. 

For my demo, Page A has a category list that, when an item is clicked, tells a detail list to fill itself with appropriate details. At present, the category and the detail are each a separate controller.

Really, I'm looking for discussion about whether this is the right way to think. But, I'm also wondering if those category and details are supposed to be in their own controllers? Am I supposed to have a controller for every operating <div> in the app? That also means that I have a separate view folder for each, probably containing only one file. That seems messy to me.

That's enough to ask but, I have one more thing to toss in. On the JMVC website, I see that I can execute a statement like:

TodosController = Controller.extend("todos",{...));

Where "todos" refers to a DOM element named "todos" (id?). Is this how I should be creating my category and detail controllers?

Thanks for any advice.

Today's First Tidbit: IE, jQuery and the Title tag

Firefox will allow you to use jQuery to assign a value to the <title> of a page. IE will not. It gives you an error deep in jQuery: 

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)
Timestamp: Fri, 26 Feb 2010 17:08:14 UTC

Message: Unexpected call to method or property access.
Line: 260
Char: 5
Code: 0

Fortunately, document.title='Cool New Title'; works on both and with javascsriptMVC.

FYI

Separation of Concerns - ChaChing!!

I made JavascriptMVC work. My demo app is now structured into three controllers: document, category and detail. It has two views, one for the category and one for the details.

The document controller generates html containers for the other two and associates their controllers with their <div>s. I am, so far, treating each segment of the browser window as a separate page. That feels pretty close to right to me.

The category controller has a built-in init function that runs an ajax call to the C# Model to collect it's clickable listing.

When a click is made on a category, it publishes a Get.The.Details event and updates the user interface. The detail controller senses that (I love that JMVC has made that completely invisible to me) and issues another ajax call to get the details.

I think I am going to love this. It is so wonderful to have places to put code in Javascript. I think of all the time I have spent scrolling up and down .js files looking for where I set the X or the Y thingy.

The only thing that's been really difficult so far is Scope. I did find "this.view()" in the video as Justin suggested, but it turns out that callbacks often don't have a good Scope and, until I learn something new, that's going to be a source of hassle and less generalized code than I want.

Here are two things that solved problems for me:

Getting the DOM element when it wasn't part of the scope: 
target=param.currentTarget;

Getting the current object when it wasn't coming through well:  
this.element.html(html);

Honestly, I don't understand it, but, it appears that Scope is going to be my bete noir for the time being. I suffer from it in C#, too.

Lots to learn but, it's been a good day.

Another milestone

I made JavascriptMVC work. My demo app is now structured into three controllers: document, category and detail. It has two views, one for the category and one for the details.

The document controller generates html containers for the other two and associates their controllers with their <div>s. I am, so far, treating each segment of the browser window as a separate page. That feels pretty close to right to me.

The category controller has a built in init function that runs an ajax call to the C# Model to collect it's clickable listing.

When a click is made on a category, it publishes a Get.The.Details event and updates the user interface. The detail controller senses that (I love that JMVC has made that completely invisible to me) and issues another ajax call to get the details.

I think I am going to love this. It is so lovely to have places to put stuff in Javascript. I think of all the time I have spent scrolling up and down .js files looking for where I set the X or the Y thingy.

The only thing that's been really difficult so far is Scope. I did find "this.view()" in the video as Justin suggested, but it turns out that callbacks often don't have a good Scope and, until I learn something new, that's going to be a source of hassle and less general code than I want.

Here are two things that solved problems for me:

Getting the DOM element when it wasn't part of the scope: target=param.currentTarget;

Getting the current object when it wasn't coming through well: 
 this.element.html(html);

Honestly, I don't understand it, but, it appears that Scope is going to be my bete noir for the time being. I suffer from it in C#, too.

Lots to learn but, it's been a good day.

JavascriptMVC Looks Pretty Good

Note the change in spelling. It's not "Javascript MVC". I've excised the space. It turns out that 1) google is much friendlier to inquiries about "JavascriptMVC" and 2) the man behind the framework, Justin Meyer, thinks that's the correct spelling. If his code is good enough for  me, then so is his spelling. Plus he reached out personally, so I am now a loyal friend.

Anyway, this looks like it's going to work. I got it installed in Visual Studio (though I am seriously thinking about moving out of there soon for these Javascript projects). 'Hello World' came up smoothly. It took stepping through the code in Firebug to figure out what folder to put my style sheets in ("stylesheets", not "styles" or "css" or, whatever), but the framework includes them correctly. 

I am having a bit of a hassle trying to get the system to recognize a view. The documentation wiki  has a nice page that purports to explain how to use the view/templating system. I created a simple template and tried to activate it with the code on the page "html= new View..." but it didn't work. I asked on the google group and was told to review the getting started video. I did and, yes, there was a line of code that was different ("this.view('viewName'..."). I'm not sure what the example on the wiki page is about, but what the heck, it is progress.

Next up, mime types. I'm using IIS7 and that means that it won't just serve any old file. In particular, it won't serve the javascript template files with the extension ".ejs".

First, .htaccess == website.config. They are entirely different. .htaccess is an antique format with inscrutable language. website.config is a modern (xml) format with inscrutable language. The cool thing is that you can define mime types in website.config. If that's possible with .htacess, I've not run into it. You can find an explanation and the source of my code sample on a nice IIS website, here.

I added code to tell it to serve .ejs files as text/javascript and it seems to get them. Still doesn't work, but that's why I continue to be alive. To make things work.

A Small Moment of Victory

I have been trying to reorganize the site to reflect the separation between Javascript (View/Controller) and C# (Model) alongside the Javascript framework effort. I have finally succeeded.
I now have two Visual Studio projects. One is ASP.NET MVC. It connects to the database. It serves JSON objects (see my explanation of the Category/Detail demo app below). The other is pure Javascript (it has a working installation of Javascript MVC for now). I also have configured IIS7 to have a domain sandbox.local that points to the Javascript site. In addition, it has a subordinate application, sandbox.com/data, that points to the ASP.NET MVC project.

I grabbed my previous AJAX demo page and moved it to the Javascript project. Revised it so that the jQuery Post URLs point to "data/..." and Voila!! I have a working project.

Installing Javascript MVC

Some of this was learned during my Sproutcore effort but, since I am writing this series of posts post-facto, here is the overall understanding.

First, Visual Studio is a Microsoft product and, as such, sucks. I know, I know, many developers consider it to be wonderful. Intellisense, the code completion and context-sensitive documentation function is great. It's tight integration with IIS is very helpful, as is its integration with MS SQL.  But it also is cumbersome and bloated. Worse, it doesn't have Eclipse's ability to expand an editor to fill the whole window and then shrink again. That means that one is forever forced to look at code through a little, tiny window. They say that VS 2010 will have multiple-monitor support. Maybe then it won't suck.

Anyway, that is only the beginning of the suckage. I want to add Javascript MVC to my site. Actually, I really want it to be a separate project. I'd actually like it to be a separate website. I'd like to have it be the main website and I'd like to have the C# stuff, aka, the Model Layer, be connected only by AJAX calls that return JSON. I want no other interaction between them.

It turns out that Javascript won't allow you to access a different domain for security reasons. Good thinking, but it means that I need to have another angle. Since Javascript MVC is the user interface, I would like it to present itself when a user goes to mydomain.com. That says that the Model Layer would be good at say, mydomain.com/modellayer, or whatever. Javascript would let me access it. Life is good.

I tried doing it with a Virtual Directory. No dice. I don't know why, but it said it needs to be an application. Google google. Turns out that there is an option, right next to the virtual directory on the popup to add an application. Cool Beans. Another step on the road to happiness.

Actually, I have to be honest. I spent a whole bunch of time cursing IIS. I got a message that said it coudn't show the directory. Nothing I did affected the display. Since I assume that IIS is doing invisible, mysterious crap, I thought that it needed something special to see the files in the folder, especially since there is no index.php analog in this project. I learned a great deal about how website.config works and global.asax.cs but no cigar. Then I got the idea to turn on Directory Listing and see if I could click on something.

I was pointing to the wrong directory!!!! Visual Studio in its infinite wisdom has lots of directories named 'sandbox'. I pointed at the one enclosing the good one. Fixed and works.

One other thing. I tried, during this thrashing, to place Javascript MVC into a directory inside my sandbox project. I never could figure out a way to do it. "Add Existing Item" doesn't work. Neither does adding a directory full of stuff to the file system inside it. Nothing. Never did get it to work, but that's good. I settled on a better approach. mydomain.com and mydomain.com/data is just what I want.

The Framework Issue Expands

With Sproutcore gone, Javascript MVC is next on my list. It's a cleaner looking package that doesn't appear to try to do so much (Sproutcore had a million kinds of controls and other stuff to go along with it). I watched their introductory videos (this is a great new trend in software) and think it might be ok.

But, while I was at it, I looked around for other information about the topic and ran into the guys at Yahoo who are doing YUI, or more specifically the next version, YUI3. This is not a Javascript MVC replacement. It's more of a jQuery targeted at serious application development. jQuery can, and is, used by plenty of serious people, but here is another level of complexity. I am more familiar with YUI's renegade child, EXT JS. From what I can see, they are similar in intent.

EXT JS was amazing. It allowed one to, in a very, very short time, create highly capable tables of data with a lot of tasty controls and features that just came straight from the framework. It was very, very complicated to learn, but the guys that did so (I was a novice), were able to crank up some serious business. It is my understanding that YUI was a precursor to EXT JS and is striving toward much the same goal.

Listening to the YUI3 people doing a presentation to some sort of user group, I was impressed by their intention to make YUI work in a way that is very consistent with the basic ideas of the DOM. Since this is the foundation of every web browser presentation layer and, thus, every application, that seems like a really good thing. Further, the main thing I thought about EXT JS was that it felt like none of my previous knowledge really helped me master it.

The other thing they talked about, that I had forgotten about and that I liked very, very much, was the ability to create custom events. It's nice to have "onclick", etc, but sometimes I want to have an "onStupidUser" event that allows me to do something outside the normal flow. I used this a lot in my work with EXT JS. The YUI guys talked about some good improvements upon the theme.

What's it all mean? Well, two things. First, it reminded me that I may not be satisfied with only jQuery. Second, it reminded me that I may not be satisfied with only jQuery and Javascript MVC. It seems fully possible that I will want to add YUI3 or EXT JS to the kit. That would push jQuery back to the role of user interface sugar maker, good for decorations, etc, but leaving the heavy lifting of data display and interaction to one of the more formalized user interface systems.

But, it's a series of decisions for another day.

Sproutcore Bites the Dust

When I wrote my inaugural empty <div> Ajax application last summer, I figured out some things. One is that the View and Controller layers of MVC will eventually be entirely written in Javascript. The other is that writing an application in Javascript is like any other language, it really needs some sort of structure to avoid code that is difficult to understand or change.

Though I suppose there might be other structures that are as good (maybe), I find MVC to be a natural and pleasing way to organize code. The "separation of concerns" is about right. I can usually find a place that seems right for whatever bit I want to add to a site and, even more importantly, I can find and understand it later. 

Javascript makes life even more difficult because of it's strongly event-driven nature. One needs to separate the (in jQuery jargon) $.ready() code from things you want to run immediately. There are event handlers and a ton of other functions and objects that are needed to handle callbacks on them. AJAX ends up complicating it further with a whole other set of events and functions needed to process data as it comes and goes.  It is a mess.

So, I searched for Javascript MVC. Happily, I came up with a nice handful of options. Among them, I had heard of Sproutcore. It has been adopted by Apple for it's javascript apps and gets a lot of nice conversation among the smart kids on the web. I read about others and settled on it and a project named, appropriately enough, Javascript MVC as the likely candidates. 

I spent much of yesterday working on Sproutcore and have eliminated it from my competition. I am pained by how complicated and foreign it is. I watched and read several instruction things about it and, it's not like any javascript I've ever seen. I mean, I recognize the language constructs, but the conduct of development in it is way too much like .NET before .NET MVC. Lots of magical things to configure. I might have stuck with it except for it's other major resemblance to .NET: not only doesn't it develop like other web languages, it doesn't deploy like other javascript thingies.

To install Sproutcore, I first had to install Ruby/Webrick. I love the idea of Ruby, but having to add a third language to my life at this moment is a troubling addition to the already overwhelming complication of my technology. Then, it turns out that in development, you can't view its function in the normal way. To look at it, you need to use Webrick, a small, configurable (and cool) web serving tool. I didn't bother to truly comprehend, but it appears that Webrick executes some Ruby scripts to reorganize the Sproutcore system in a way that is servable. I made it work and couldn't figure out anything about what it was doing. I learned that there is a special build step to package it up for deployment on an external server. I don't know how you can trust how it's going to behave or what to do to debug and modify after. I do not like it.

I researched it for probably longer than I should, trying to figure out what I could do to connect it to my existing C# tools. That is, after all, where the model layer will be. Though Sproutcore has facillities that supposedly help it do that (that's the point, after all), the problem of doing so in a .NET context are just huge. Add the whole Ruby/Webrick deal and, fuhgedaboudit.