Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • A control should have one javascript file and one HTML template file with the same name.
    example: html/BillingShippingAddress.html and js/BillingShippingAddress.js

  • A control's name should unique and meaningful and should not duplicate.
    example: BillingShippingAddress.html and BillingShippingAddress.js

  • A javascript variable will be created that will act as a collection for all of the controls objects. 
    example : var eb_billingShippingAddress = eb_billingShippingAddress || {};

  • Control's properties, functions and methods name should start with came case.
    example: productCatalogPage

  • Any object at the collection level should be generic to all instances of that control. Instance-specific information should live at the model level. SitePath, TemplatePath and ServicePath would be fixed properties for each control. These variables should be prefixed with an eb_prefix so that it does not collide with other JavaScript systems.
    example : 
    eb_billingShippingAddress.SitePath = eb_Config.SitePath;
    eb_billingShippingAddress.TemplatePath = "html/BillingShippingAddress.html";
    eb_billingShippingAddress.ServicePath = eb_Config.ServicePath;

  • The Path of the HTML template should mirror that of the path to the JS.
    example: eb_billingShippingAddress.TemplatePath = "html/BillingShippingAddress.html";

  • Each model's properties should be defined camel case and assign observable / observableArray based on requirements. it would start _that / _self scope variables. 
    example: var _that = this;
     _that.domElement = options.domElement;

    _that.showError = ko.observable(0);
    _that.errorMessage = ko.observable();
    _that.showSuccess = ko.observable(0);
    _that.successMessage = ko.observable();
    _that.billingAddress = ko.observableArray();

  • Each model's function's name should be meaningful and scope should be model's context.
    example:

    _that.toggleShipping = function () {
    _that.shippingAddressCollapse(!_that.shippingAddressCollapse());
    };

  • If there is more than one model for a control, a collection called models will be added to the control collection.
  • Sitewide settings such as the dom, service data, template path and dependent objects etc. will be passed into the control's javascript collection at the time of model creation.
    example : 

    eb_billingShippingAddress.model = function (options) {
    var _that = this;........}

  •  A render function should exist on each control.
    • Its job is to grab the template and insert it into a dom element that is passed into the function.
    • It should accept a user-supplied template in the place of the default template.

 

example: 

eb_billingShippingAddress.render = function (options) {
var defer = jQuery.Deferred();

...

$.get(options.templatePath).done(function (data) {
options.domElement.innerHTML = data;
defer.resolve(data);
}).fail(defer.reject);
return defer.promise();
};

 

  • GET service call method should be control leve with parameters and deferred object handling.
    example: 

    eb_billingShippingAddress.createAddressRecord = function (data, personId) {
    var defer = jQuery.Deferred();
    console.info('create address record...');

    if (!personId || personId <= 0) {
    throw { type: "argument_null", message: "personId property is required.", stack: Error().stack };
    }
    if (!data) {
    throw { data: "argument_null", message: "data property is required.", stack: Error().stack };
    }
    var service = eb_billingShippingAddress.newAddressService.replace("{personId}", personId);

    $.ajax({
    url: service,
    crossDomain: true,
    type: "POST",
    data: data,
    xhrFields: {
    withCredentials: true
    }
    }).done(function (result) {
    defer.resolve(result);
    }).fail(defer.reject);
    return defer.promise();
    };

  • PATCH service call method should be control leve with parameters and deferred object handling.
    example: 

    eb_billingShippingAddress.updateProfileAddressRecord = function (data, addressName, personId) {
    var defer = jQuery.Deferred();
    if (!personId || personId <= 0) {
    throw { type: "argument_null", message: "personId property is required.", stack: Error().stack };
    }

    if (!addressName) {
    throw { type: "argument_null", message: "addressName property is required.", stack: Error().stack };
    }

    if (!data) {
    throw { data: "argument_null", message: "data property is required.", stack: Error().stack };
    }

    console.info('update address...');
    var service = eb_billingShippingAddress.updateProfileAddressService.replace("{personId}", personId).replace("{addressName}", addressName);
    $.ajax({
    url: service,
    type: "PATCH",
    contentType: "application/json",
    data: JSON.stringify(data),
    xhrFields: {
    withCredentials: true
    }
    }).done(function (result) {
    defer.resolve(result);
    }).fail(defer.reject);
    return defer.promise();
    };

  • POST service call method should be control leve with parameters and deferred object handling.
    example: 

    eb_billingShippingAddress.createAddressRecord = function (data, personId) {
    var defer = jQuery.Deferred();
    console.info('create address record...');

    if (!personId || personId <= 0) {
    throw { type: "argument_null", message: "personId property is required.", stack: Error().stack };
    }
    if (!data) {
    throw { data: "argument_null", message: "data property is required.", stack: Error().stack };
    }
    var service = eb_billingShippingAddress.newAddressService.replace("{personId}", personId);

    $.ajax({
    url: service,
    crossDomain: true,
    type: "POST",
    data: data,
    xhrFields: {
    withCredentials: true
    }
    }).done(function (result) {
    defer.resolve(result);
    }).fail(defer.reject);
    return defer.promise();
    };

  • DELETE service call method should be control leve with parameters and deferred object handling.
    example:

    eb_billingShippingAddress.deletePersonAddressRecord = function (addressName, personId) {
    var defer = jQuery.Deferred();
    if (!personId || personId <= 0) {
    throw { type: "argument_null", message: "personId property is required.", stack: Error().stack };
    }

    if (!addressName) {
    throw { type: "argument_null", message: "addressName property is required.", stack: Error().stack };
    }

    console.info('delete address...');
    var service = eb_billingShippingAddress.deletePersonAddressService.replace("{personId}", personId).replace("{addressName}", addressName);

    $.ajax({
    url: service,
    type: "DELETE",
    xhrFields: {
    withCredentials: true
    }
    }).done(function (result) {
    defer.resolve(result);
    }).fail(defer.reject);
    return defer.promise();
    };

  • Each service call should have handled with Jquery Deferred object with deferred.resolve(data), defer.reject and defer.promise().
  • Service's fails case should be handled properly and write a meaningful error message based on the frontend error message requirement. We have handled three different way error messages.  
    • Error log in browsers console : Console.info("error message"); Console.error("error message"); 
    • Frontend side predefined error messages under the knownResponses method :  _that.errorMessage(eb_billingShippingAddress.knownResponses[2].message);
    • Error Message from service side: _that.errorMessage(data.responseJSON.message);

  • Knockout validations: Read ---------- confluence page.

...