Apply Business Logic Like CSS
Providing a rich client experience in the browser has been something that we (as a community) have been trying to do for as long as I can remember. You don't have to look very hard to see the evolution of our attempts. Over the course of a decade or so there have been several efforts to make this a reality: ActiveX controls, Java applets, Flash, and Silverlight are just the ones that I can name off the top of my head. As support for ECMAScript 5 grows (and with the death of Internet Explorer 8 just around the corner), we're finally in an era where we can provide a rich client experience in the browser with nothing more than JavaScript.
This is certainly an exciting time, but just because the technology is available, that doesn't mean developer adoption is guaranteed to be high. Why is this? Surprisingly, most of the developers that I'm aware of are happy relying on the server-side technology they're so comfortable with; the shift to a thick-client in the browser means that a lot of developers will need to be pushed out of their comfort-zone. I think this is an incredibly promising area, but many developers will need to be introduced to the concepts slowly in order to get buy in.
Admittedly, when I first tried to push more interactivity to the client I was a little lost. In my latest project I decided that we'd try to layer in more client-side interactivity than we've done in the past, but I wanted to do it in a maintainable way. I didn't want it to be bolted on at the end of the project with jQuery plugins; I wanted the interactivity to have first-class support in our application. I also didn't want beautifully structured server-side code that does a hand-off to client-side code that's spaghetti. After all, a rich client isn't worth it if it's a nightmare to maintain.
Over the last few years I've had my eye on Knockout and the ecosystem surrounding it. Based on everything that I knew about it, it would be a good addition to Microsoft's standard MVC stack. The problem with vanilla Knockout is that there isn't a good separation of concerns when it comes to your views and the logic to display them. For instance, a standard Knockout view would have snippets JavaScript code throughout it like this:
<div data-bind="visible: myFunction() > myValue"> Some Text </div>
Obviously that's a simple example, but as you build more complex logic these inline JavaScript snippets can get out of hand. Luckily there is a handy plugin that allows you to pull this logic out and apply it to your view like CSS tags:
<script> var bindings = { myClass: function(context, classes) { return { visible: this.myFunction() > this.myValue } } }; </script> <div data-class="myClass"> Some Text </div>
I've left out the standard Knockout code to bind everything together, but hopefully you can see that this will allow you to completely separate your view from the logic behind it. Just getting that separation is a huge benefit, but you can do something much more powerful with this basic construct. With CSS you define small reusable classes and then combine them on your view to build a more complex style. Just like CSS, you can begin to apply functional behavior the same way:
<script> var bindings = { show: function(context, classes) { return { visible: this.isMessageVisible() } }, message: function(context, classes) { return { text: this.getMessage() } } }; </script> <div data-class="show message"> Message will be shown here. </div>
This simple concept allows you to build tiny reusable pieces that define behavior. You can then apply multiple behaviors to individual elements (or a hierarchy of elements) to compose more sophisticated behaviors. In my latest web application I've built behavioral classes for tons of basic things: show, hide, valid, invalid, enable, disable, and other more complex classes that represent common behaviors in my business logic.
This method could certainly use some improvements, which I hope to work on in the future, but this is still miles ahead of where we were a few years ago.