JavaScript Patterns - DataService

HTML

<script src="http://knockoutjs.com/js/jquery.tmpl.js"></script>
<script src="https://gist.github.com/raw/954961/0c3b6375afd4e886da49e99bd68c68ea6a7121f5/ko-1.3ctp.debug.js"></script>
<script src="https://github.com/SteveSanderson/knockout.mapping/raw/master/build/output/knockout.mapping-latest.debug.js"></script>
<div data-bind="if: model">
    <p>
        First Name: <span data-bind="text: model().FirstName" />
    </p>
    <p>
        First Name:
        <input data-bind="value: model().FirstName" /></p>
    <p>
        Last Name: <span data-bind="text: model().LastName" />
    </p>
    <p>
        Full Name: <span data-bind="text: fullName" />
    </p>
    <h2>
        Friends (<span data-bind="text: model().Friends().length"></span>)</h2>
    
    <ul data-bind="template: {name : 'friendsTemplate', data: model, foreach:model().Friends}">
    </ul>
    
    <button data-bind="click: addFriend, enable : model().Friends().length < 5">
        Add Friend</button>
    <button data-bind="click: save">
        Save Friend</button>
    <button data-bind="click: load">
        Refresh Data</button>
</div>

<script type="text/x-jquery-tmpl" id="friendsTemplate">
    <li>
        ${ $data.Name } - ${ new Date }
        <input data-bind="value: Name"/>
        <button data-bind="click: function() {papa.viewModel.remove($data)} ">Remove</button>
        <label>
            <input type="checkbox" data-bind="checked: IsOnTwitter"/>
            is on twitter
            <input data-bind="value: TwitterName, visible: IsOnTwitter"/>
        </label>
    </li>
</script>

JavaScript

var papa = {};

// Ajax Service
// John Papa
// Depends on scripts:
//                         none
papa.AjaxService = function() {
    var serviceBase = '/Home/';

    var getSvcUrl = function(method) {
        return serviceBase + method;
    };

    var getJSON = function(method, jsonIn, callback) {
        $.getJSON(getSvcUrl(method), jsonIn, function(json) {
            callback(json);
        });
    };

    var ajaxPost = function(method, jsonIn, callback) {
        $.ajax({
            url: getSvcUrl(method),
            type: "post",
            data: jsonIn,
            contentType: "application/json",
            success: function(json) {
                callback(json);
            }
        });
    };
    return {
        ajaxPost: ajaxPost,
        getJSON: getJSON
    };
}();


// Person Data Service
// John Papa
// Depends on scripts:
//                         papa.ajaxservice.js
papa.PersonDataService = function() {
    var getPersons = function(callback) {
        papa.AjaxService.getJSON("GetPersons", null, callback);
    };
    var savePerson = function(person, callback) {
        papa.AjaxService.ajaxPost("Save", person, callback);
    };

    return {
        savePerson: savePerson,
        getPersons: getPersons
    };
}();

papa.ModelFactory = function() {
    var createFriend = function(name) {
        return {
            Name: ko.observable(name),
            IsOnTwitter: ko.observable(false),
            TwitterName: ko.observable()
        };
    };
    return {
        createFriend: createFriend
    };
}();

papa.PersonViewModel = function() {
    this.model = ko.observable();
    this.addFriend = function() {
        //this.model().Friends.push(new friend("Sample Friend"));
        this.model().Friends.push(papa.ModelFactory.createFriend("sample friend goes here"));
    };
    this.save = function() {
        // turns it into a json string (not a json object)
        // person =...