2009-12-13 2 views
1

Je suis sur le point de faire une application web qui aura une extrémité client assez lourde. Je ne suis pas sûr de la façon d'organiser mon code javascript, mais voici une idée de base:javascript code architecture question

// the namespace for the application 
var app = {}; 

// ajax middle layer 
app.products = { 
    add : function(){ 
    // send ajax request 
    // if response is successful 
     // do some ui manipulation 
     app.ui.products.add(json.data); 
    }, 
    remove : function(){}, 
    ... 
}; 
app.categories = { 
    add : function(){}, 
    .... 
}; 

// the ui interface which will be called based on ajax responses 
app.ui = {}; 
app.ui.products = { 
    add : function(product_obj){ 
    $('#products').append("<div id='"+product_obj.id+"'>"+product_obj.title+"</div>"); 
    } 
}; 
app.ui.categories = {}; 

Quelqu'un a des expériences similaires pour me dire les avantages et les inconvénients de cette approche? Quelle est votre façon de concevoir l'architecture de code javascript côté client? Merci. [Update]: Cette application web, comme vous le voyez ci-dessus, traite des produits CRUD, catégories CRUD seulement de manière ajax. Je montre seulement un extrait ici, alors vous savez ce que j'essaie de réaliser et quelle est ma question. Encore une fois, je demande des intrants pour mon approche pour organiser le code de cette application.

+1

Euh, faites-vous vraiment Encore une autre bibliothèque JS? Avant d'investir le temps, la douleur, et la courbe d'apprentissage de l'obtenir à travers N plates-formes, toutes légèrement brisées de différentes manières, regardez jQuery, YUI, etc., etc. Mon favori personnel est jQuery, mais presque tout est meilleur que en construire un nouveau à partir de zéro. –

+1

@Peter: non. regarde mon code, je n'essaye pas de construire une librairie JS. J'essaie de développer une application web avec un client lourd. Je demande des conseils architecturaux. – Shawn

+2

il pose des questions sur l'organisation du code.sans cela, tout le jQuery dans le monde ressemble à des ordures. – seanmonstar

Répondre

3

Cela ressemble à la façon dont je fais mes projets JavaScript. Voici quelques astuces que j'ai utilisées:

  • Créez un fichier pour chaque objet singleton. Dans votre code, stockez l'interface ajax, middle et ui dans des fichiers distincts
  • Créez un objet global singleton pour les 3 couches habituellement dans le projet; Interface graphique, Backend et App
  • N'utilisez jamais d'ajax pur de n'importe où en dehors de l'objet Backend. Enregistrez l'URL sur la page côté serveur dans l'objet Backend et créez une fonction qui utilise cette URL pour contacter le serveur.
  • Avoir une classe JSON sur le serveur qui peut signaler les erreurs et les exceptions au client. Dans l'objet Backend, vérifiez si l'objet JSON renvoyé contient une erreur et appelez la fonction serverError dans la classe GUI pour présenter l'erreur à l'utilisateur (ou au développeur).

Voici un exemple d'un objet Backend:

var Backend = {}; 
Backend.url = "/ajax/myApp.php"; 
Backend.postJSON = function(data, callback){ 
    var json = JSON.stringify(data); 
    $.ajax({ 
    type: "POST", 
    url: Backend.url, 
    data: "json="+json, 
    dataType: "json", 
    success: function(response){ 
     if(response){ 
     if(response.task){ 
      return callback(response); 
     }else if(response.error){ 
      return Backend.error(response); 
     } 
     } 
     return Backend.error(response); 
    }, 
    error: function(response){ 
     Backend.error({error:"network error", message:response.responseText}); 
    }, 
    }); 
}; 
Backend.error = function(error){ 
    if(error.message){ 
    Client.showError(error.message, error.file, error.line, error.trace); 
    } 
}; 

Cela peut être améliorée en stockant l'somewher objet ajax dans l'objet backend, mais il n'est pas nécessaire.

+0

@Marius: Pourriez-vous être plus précis sur "Stocker l'URL de la page côté serveur dans l'objet Backend et créer une fonction qui utilise cette URL pour contacter le serveur.". Merci. D'autres points je suis totalement d'accord. – Shawn

+0

@Marius: Je l'ai maintenant. Je prenais une approche similaire dans mes projets précédents. La règle ici, je pense est d'utiliser une seule couche pour le streaming de données client-serveur. – Shawn

+0

@Shawn: Je suppose que l'idée de Marius est d'avoir un endroit centralisé pour gérer la communication. – Codism

0

Lorsque vous construisez quelque chose de non trivial, l'encapsulation est importante pour rendre les choses maintenables à long terme. Par exemple, JS UI n'est pas simplement de simples méthodes JS. Les composants de l'interface utilisateur sont constitués de css, de modèle, de logique, de localisation, d'actifs (images, etc.). Il en est de même pour un module de produit, il peut avoir besoin de ses propres paramètres, bus d'événement, routage. Il est important de faire du code architectural de base en intégrant l'ensemble de bibliothèques que vous avez choisi. Cela a été un défi pour moi lorsque j'ai commencé le développement JS à grande échelle. J'ai compilé quelques bonnes pratiques dans une architecture de référence au http://boilerplatejs.org pour que quelqu'un puisse utiliser l'expérience que j'ai acquise.

0

Pour la gestion ajax côté client, j'ai un objet URL qui contient toutes mes URL et que j'ai un objet ajax qui gère l'ajax. Ce n'est pas une approche centrée. Dans mon cas, j'ai des URL différentes qui traitent différentes tâches. Je passe également une fonction de rappel à exécuter dans l'objet ajax.

var controller_wrapper = { 
    controller: { 
    domain: "MYDOMAIN.com", 
    assets: "/assets", 
    prefix: "", 
    api: { 
     domainer: "http://domai.nr/api/json/info", 
     tk_check: "https://api.domainshare.tk/availability_check" 
    }, 
    "perpage": "/listings/ajax", 
    "save_image": "/members/saveImage", 
    "update": "/members/update", 
    "check_domain": "/registrar/domaincheck", 
    "add_domain": "/registrar/domainadd", 
    "delete_listing": "/members/deactivateProfile", 
    "save_listing": "/members/saveProfile", 
    "get_images": "/images/get", 
    "delete_image": "/images/delete", 
    "load_listing": "/members/getProfile", 
    "load_listings": "/members/getListings", 
    "loggedin": "/members/loggedin", 
    "login": "/members/login", 
    "add_listing": "/members/add", 
    "remove": "/members/remove", 
    "get": "/members/get", 
    "add_comment": "/members/addComment", 
    "load_status": "/api/loadStatus" 
} 
} 

    var common = { 
    pager: 1, 
    page: 0, 
    data: { 
    saved: {}, 
    save: function (k, v) { 
     this.saved[k] = v; 
    } 
}, 
ajax: { 
    callback: '', 
    type: 'POST', 
    url: '', 
    dataType: '', 
    data: {}, 
    add: function (k, val) { 
     this.data[k] = val; 
    }, 
    clear: function() { 
     this.data = {}; 
    }, 
    send: function() { 
     var ret; 
     $.ajax({ 
      type: this.type, 
      url: this.url, 
      data: this.data, 
      dataType: this.dataType !== '' ? this.dataType : "json", 
      success: function (msg) { 
       if (common.ajax.callback !== '') { 
        ret = msg; 
        common.ajax.callback(ret); 
       } else { 
        ret = msg; 
        return ret; 
       } 
       return; 
      }, 
      error: function (response) { 
       console.log(response); 
       alert("Error"); 
      } 
     }) 
    } 
} 
    var callback = function (results) { 
    console.log(results 
    } 
    common.ajax.callback = callback; 
    common.ajax.type = "jsonp"; 
    common.ajax.type = "POST"; 
    common.ajax.url = controller_wrapper.controller.perpage; 
    common.ajax.add("offset", common.page); 
    common.ajax.add("type", $("select[name='query[type]']").val()); 
    common.ajax.add("max", $("select[name='query[max]']").val()); 
    common.ajax.add("min", $("select[name='query[min]']").val()); 
    common.ajax.add("bedrooms", $("select[name='query[bedrooms]']").val()); 
    common.ajax.add("sort", $("select[name='query[sort]']").val()); 
    common.ajax.send();