Jensen Ching
Jensen Ching

Reputation: 3164

Linking parts of a single-page web application

I am working on a single-page web site targeted for mobile users (eventually going to be ported to Phonegap). I have broken down my screens into 'cards', which are basically just <div>s that I am showing/initializing/hiding as needed.

Currently I am having trouble deciding on the proper structure to use in order to implement linking these panels together into a coherent app. My current implementation goes something like this (currently using Knockout as I am familiar with it):

//Javascript
var LoginCard = function() {
    this.goToRegister = function() { 
        // IF registerCard is not initialized
        // THEN ko.applyBindings(new RegisterCard(), document.getElementById('registerCard'));
        // ELSE $('#registerCard').show();
    };
    this.doLogin = function() { /* Goes to home card after login */ };
}
var RegisterCard = function() {
    this.goToLogin = function() { /* Goes back to login card */ };
    this.doRegister = function() { /* Goes to login card after reg */ };
}
ko.applyBindings(new LoginCard(), document.getElementById('loginCard'));

//HTML
<div id="loginCard">
    <button data-bind="click: goToRegister" id="btnReg">Register Account</button>
    <button data-bind="click: doLogin" id="btnLogin">Login</button>
</div>
<div id="registerCard">
    <button data-bind="click: goToLogin" id="btnBackToLogin">Back To Login</button>
    <button data-bind="click: doRegister" id="btnDoReg">Submit Registration</button>
</div>

As you can see, the linking occurs within the view model itself, so the different view models (e.g. loginCard, registerCard, homeCard) become tightly coupled with each other.

A more "low-level" alternative would just be to use jQuery to bind the button events so that each card does not have to know details about the other cards:

//But this means I have to specify a ton of unique IDs for all the elements in the page.
$('#btnReg').click(function() { /* Initialize and go to registerCard. */ });

I also thought of using hash-routing/pushState so while the click events are still inside each view model, all it has to know is the URL to go to? Something like:

var LoginCard = function() {
    this.goToRegister = function() { 
        window.location.hash = 'register';
        //or history.pushState('state', '', 'register';
    };
}

This is my first attempt at creating a single-page application, so I am really confused about design choice. Which one would be better, or can anyone suggest the standard way to go regarding this?

Upvotes: 0

Views: 121

Answers (1)

Ray
Ray

Reputation: 4108

I recommend you to create another object for the routing which depends on routing library such as SammyJS or CrossroadsJS.

Please refer my hobby project, MyStory.Spa, it is also single page application style web (not for the mobile app), which is using SammyJS for browser level routing. In the MyStory.Spa architecture, webapp/app/infra/router.js takes a role for the routing and detailed information about routing, view, viewmodels are in the /webapp/app/infra/routing.table.js.

In this way you can decouple View, ViewModel, Model, Data Service, Routing and so on.

Upvotes: 1

Related Questions