Patterns for Jitsu

Jitsu represents a departure from traditional web programming. This document takes a moment to describes some of the ways to take advantage of Jitsu's programming model.

1. Use controls to avoid duplicated markup.

Guideline: Don't repeat markup unless you have to.

In many web apps you often see markup copied and pasted multiple times into a document, with little variation for each version.

A markup control:

Avoid redundant markup in Jitsu. Create a custom markup control instead (see Extending Controls in Markup for examples.

2. Keep controls private to a page

Guideline: The server should not directly address controls on the page.

Consider this fragement of an application:

    <script>            

    function processMessageFromSever(json) {
        var msg = eval(json);
        
        var name = msg.statusName;
        var msg = msg.statusText;
        
        var statusControl = document.apps[0].getControl(name);
        control.setValue(ID_text, msg);
    }    

    </script>            
    
    <!-- Create a label that to show status messages -->
    <j:Label controlId="mainStatus"/> <br/>
    
    <!-- Rest of the app here -->

Here, when a message from the server is received, the script extracts the name of a control from the message and then sets a property directly on that control.

Though this approach is short and simple, it should be avoided. Here's why:

The Jitsu cruncher preserves names in all of your data model. So in general the pattern here should be:

The server addresses the data model. Controls then bind to that data model.

In this case, you could define a small dataset:

    <j:define targetNamespace="urn:myapp">
        <j:type name="ProgressStatus">
            <j:property name="message" />
        </j:type>
    </j:define>

    <body>
        <j:App>
            <!-- create a "progress" dataset -->
            <j:data>
                <j:DataSet id="progress" xmlns:myapp="urn:myapp">
                    <myapp:ProgressStatus id="mainStatus"/>
                </j:DataSet>
            </j:data>

            <j:script>            
            function processMessageFromSever(json) {
                var msg = eval(json);

                var name = msg.statusName;
                var msg = msg.statusText;

                var dataSet = document.apps[0].getDataSet(ID_progress);
                dataSet.getValue(name).setValue(ID_message, msg);
            }    
            </j:script>            
            
            <!-- Create a label that binds to the progress status -->
            <j:Label text="bind(data.progress.mainStatus.message)"/> <br/>
            
            <!-- Rest of the app here -->
        </j:App>
    </body>

Although the code is a little longer, now the backend addresses a dataset rather than a control on the page. This pattern helps ensure your backend and frontend remain decoupled, and also works with the cruncher.

Beware of setValue on Controls

In traditional GUI programming, you see code like this (C# WinForms) code:

	private void Initialize()
	{
		this.button = new System.Windows.Forms.Button();
		this.button.Text = "Next";
		this.button.Click += new System.EventHandler(this.button_Click);
        // create other components
    }

	private void button_Click(object sender, System.EventArgs e)
	{
		if (textBox1.Text == "") 
		    textBox1.Text = textBox2.Text + " " + textBox3.Text;
        panel1.Visible = false;
        panel2.Visible = true;
	}

The pattern is (1) create controls, (2) register event handlers, (3) when events occur, use property setters and getters and other widget methods to update the UI state.

Its very easy to write this kind of code, but it is also poor style in Jitsu. Here's why:

Instead of using setValue on controls, write methods that modify the page's data model. Then bind controls to that data model. Here's the guideline:

Business logic should addresses the data model. Controls then bind to that data model.