JS Open Space convivial: rendu côté client et création de wrapper

Friendly Open Space est un framework très jeune, mais sait déjà fonctionner :-)


Dans cet article sur le développement de "Friendly Open Space", nous allons maîtriser le rendu du modèle dans le navigateur et lancer l'application sur la base de données de fichiers locale.

Le cœur de l'infrastructure prend en charge deux types d'assemblage de modèles sur le client:

  1. Rendu complet côté client
  2. Une demande est faite pour rendre le modèle au serveur, suivie de sa sortie dans une fenêtre de navigateur.

Le premier mode a une caractéristique, les données nécessaires au rendu du modèle sont demandées au serveur, c'est-à-dire le client exécute des requêtes FSQL. Il n'y a pas de danger particulier à cela si vous utilisez la restriction d'accès et le module fosAccess, mais il y a la possibilité de décharger des données brutes par copie pasteur. Cependant, cette approche réduit considérablement la charge sur le serveur.

Le deuxième type de rendu est déjà dépourvu de cette fonctionnalité. Le client envoie les paramètres du modèle et reçoit déjà du serveur HTML. Oui, la charge sur le serveur augmentera certainement, mais cette méthode est plus adaptée aux solutions Internet ouvertes.

Préparer l'application et la configurer


Et donc, nous sommes confrontés à la tâche de créer une application d'une page qui rendra 2 modèles (fenêtres) côté client. Compte tenu d'une tâche assez simple, nous nous passerons d'une base de données MySQL et de projections, nous allons donc diriger tous les travaux FSQL vers un fichier, c'est-à-dire nous utiliserons la base de données du fichier pour travailler avec les mécanismes internes du framework. Eh bien, commençons.

Créez les répertoires:

templates - répertoire des modèles
css - répertoire des fichiers css
fos - téléchargez la dernière version beta friendlyopenspace.site/en/download
Placez le favicon.ico ennuyeux dans le répertoire racine de l'application: favicon.ico

De plus, nous plaçons immédiatement les fichiers de style dans le répertoire css: window.css et styles.css

Ensuite, créez le fichier d'application application.js lui-même:

var fos = require("./fos/fos"); fos.module({ name: "application.js", dependencies: [ "fos:NServer/Application.js", ], module: function(application) { application.setSettings({ port: 3001, packages: [], dynamicLoading: true, clientRenderingMode: "client", dataClient: { defaultConnection: "default", connections: { default: { type: "file", file: "data.fosdb" } }, }, onInitialize: function(a_event) { if (!a_event.error) { application.run(); } else { console.error(a_event.error); } } }); application.getRouter().add([ { route: "", controller: "fos:NServer/NControllers/Tmpl.js", source: "templates/page.tmpl", }, { route: "/css/*", controller: "fos:NServer/NControllers/File.js", source: "css", }, { route: "/templates/*", controller: "fos:NServer/NControllers/File.js", source: "templates", }, { route: "favicon.ico", controller: "fos:NServer/NControllers/File.js", source: "favicon.ico", }, ]); application.initialize(); } }); 

Examinons maintenant le contenu du fichier application.js

Nous avons désactivé tous les packages, car ils n'étaient pas nécessaires (le paramètre packages de la méthode setSettings):

  ... application.setSettings({ port: 3001, packages: [], dynamicLoading: true, clientRenderingMode: "client", ... 

Le paramètre d'application clientRenderingMode, nouveau pour nous, est responsable du type de rendu sur le client et a deux valeurs:

"Client" - le rendu est entièrement effectué par le navigateur. Le client charge indépendamment les dépendances et exécute les requêtes FSQL sur le serveur, après quoi il collecte le code HTML lui-même

«Serveur» - le client fait une demande au serveur pour rendre le modèle et reçoit le HTML prêt comme réponse

  ... packages: [], dynamicLoading: true, clientRenderingMode: "client", dataClient: { defaultConnection: "default", ... 

Et la dernière innovation pour nous est de connecter une base de données sur un fichier. Le cadre ne peut pas fonctionner pleinement sans la capacité de traiter les variables de configuration qui ont une structure de table. Par conséquent, au lieu de MYSQL, nous utiliserons un fichier standard.

 ... defaultConnection: "default", connections: { default: { type: "file", file: "data.fosdb" } }, }, ... 

Comme on peut le voir dans l'extrait ci-dessus, dans ce cas, le type de base de données (paramètre de type) est «fichier» et le seul paramètre de connexion de fichier doit contenir le chemin d'accès au fichier de données. Si le fichier est manquant, l'application le créera par lui-même.

Créer un modèle de page


Il est maintenant temps de créer un fichier de modèle de page d'application modèles / page.tmpl, que nous avons enregistré dans la route URL racine.

 //~OPTIONS { args:{ fosInclude: ["css/styles.css"], } } //~BLOCK main default <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> %{{ render.renderHTMLHeader(); }}% <script> function onClientSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, args: { title: "Client side rendering", context: "Simple example of client side rendering" }, onResult: function(a_error, a_template){ } }); } function onServerSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, renderMode: "server", args: { title: "Server side rendering", context: "Simple example of server side rendering" }, onResult: function(a_error, a_template){ } }); } </script> </head> <body> <div class="mainwrapper"> <div class="header markup"> Client Side Rendering </div> <div class="body-wrapper markup"> <div class="body markup"> <p class="example-link--container"><a onclick="onClientSideRendering(event);">Client side rendering</a></p> <p class="example-link--container"><a onclick="onServerSideRendering(event);">Server side rendering</a></p> </div> <div class="clear-body"></div> </div> </div> </body> </html> 

Le modèle de page comporte deux liens, «Rendu côté client» et «Rendu côté serveur». Cliquer sur qui affichera les fenêtres qui ne sont pas encore disponibles. Mais il y a un code pour les appeler. Et donc traitons du code du modèle.

Lorsque nous cliquons sur le lien «Rendu côté client», nous appelons la fonction onClientSideRendering (), qui rend le modèle «templates / window.tmpl». Complètement côté client, comme dans les paramètres de l'application, le paramètre clientRenderingMode a été défini sur "client". Malgré le fait que ce soit la valeur par défaut :-).

 function onClientSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, args: { title: "Client side rendering", context: "Simple example of client side rendering" }, onResult: function(a_error, a_template){ } }); } 

La méthode de rendu rend en fait notre fenêtre et la place dans le corps de la page, comme spécifié dans la propriété de l'argument propriétaire. Nous passons 2 arguments au modèle de fenêtre: titre et contexte, en fait ce qui sera affiché dans la fenêtre affichée. Pour plus d'informations sur la méthode, voir fos :: NClient :: Application :: render

Le deuxième lien appelle la fonction onServerSideRendering (), qui affiche de la même manière le même modèle, mais côté serveur, et le client reçoit du code HTML prêt à l'emploi. Ce mode est défini dans la propriété de l'argument renderMode de la méthode de rendu sur "serveur".

 function onServerSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, renderMode: "server", args: { title: "Server side rendering", context: "Simple example of server side rendering" }, onResult: function(a_error, a_template){ } }); } 

Création d'un modèle contextuel et écriture d'un modèle d'encapsuleur


Le modèle de fenêtre contextuelle lui-même est très simple. Créez le fichier templates / window.tmpl. Voici son contenu.

 //~OPTIONS { args:{ fosWrapper: true, fosClass: "window", fosInclude: ["css/window.css"], title: "", context: "", } } //~BLOCK main default <div class="window-container"> <div class="window-close" name="close">x</div> <div class="window-title">${{args.title}}$</div> <div class="window-context">${{args.context}}$</div> </div> 

Ici, pour vous, il y a deux nouveaux paramètres fosWrapper et fosClass.

Commençons par fosWrapper. Si cet indicateur est défini sur true, le modèle HTML est placé dans le conteneur span et un objet wrapper fos :: NRender :: Wrapper est créé pour lui.

Lancez l'application, accédez à localhost : 3001 et cliquez sur le lien «Rendu côté client». La fenêtre contextuelle est notre modèle. La fenêtre popup est entièrement implémentée par css (fichier css / window.css) - Je viens de mentionner que vous ne rechercheriez pas de JS caché :-).

Ouvrez le navigateur DevTools (Ctrl + Alt + i), allez dans l'onglet Éléments et passez en revue la structure de notre fenêtre.

image

La ligne bleue sur la figure marque notre conteneur d'enveloppement span avec lequel l'objet fos :: NRender :: Wrapper est connecté.

L'argument système suivant du modèle est fosClass. Il ajoute simplement une classe CSS au conteneur d'enveloppe wrapper.

Et donc, tout a été bien fait, mais si nous essayons de fermer nos pop-ups, rien n'en sortira. Oui, nous n'avons pas encore écrit d'opération de clôture!

Comme nous l'avons dit précédemment, si l'argument système fosWrapper est vrai, l'objet wrapper fos :: NRender :: Wrapper est créé pour le modèle. Il fournit une interface standard pour interagir avec le modèle sur le client. Pour redéfinir l'encapsuleur standard d'un modèle, il suffit de créer un module avec le nom correspondant au format suivant [NOM DE MOTIF] .wrapper.js, et le module doit être hérité de la classe fos :: NRender :: Wrapper.

Créez maintenant un fichier wrapper pour le modèle templates / window.tmpl. La nouvelle classe devra fermer notre fenêtre contextuelle, lorsque vous cliquez sur le symbole "x".

Modèles de fichiers / window.wrapper.js:

 fos.module({ name: "templates/window.wrapper.js", dependencies: ["fos:NRender/Wrapper.js"], module: function(Wrapper){ return function(a_initializeOptions) { var self = this; Wrapper.call(this, a_initializeOptions); var parentAttach = this._attach; this._attach = function(a_cb) { parentAttach.call(this, function(){ fos.addDomListener(fos.select(self.getDomElement(), "[name=close]")[0], "click", function(){ self.getDomElement().classList.add("window-hide"); setTimeout(function() { self.destroy(); }, 2000); }); a_cb(); }); } } } }); 

Analysons le contenu de notre module. Tout d'abord, nous connectons la classe de base fos :: NRender :: Wrapper et en héritons via la méthode d'appel.

 fos.module({ name: "templates/window.wrapper.js", dependencies: ["fos:NRender/Wrapper.js"], module: function(Wrapper){ return function(a_initializeOptions) { var self = this; Wrapper.call(this, a_initializeOptions); ... 

Après avoir redéfini la méthode d'attachement fos :: NRender :: Wrapper :: _, qui est appelée lorsque le modèle est associé à l'objet. Dans cette méthode, nous connecterons l'événement en cliquant sur le lien pour fermer la fenêtre. La substitution se fait simplement en déclarant la méthode, mais au début, nous devons conserver la référence à l'implémentation parent. La méthode a une «nature asynchrone», nous plaçons donc l'implémentation de nos actions dans la fonction de rappel de l'implémentation parent.

  ... var parentAttach = this._attach; this._attach = function(a_cb) { parentAttach.call(this, function(){ fos.addDomListener(fos.select(self.getDomElement(), "[name=close]")[0], "click", function(){ self.getDomElement().classList.add("window-hide"); setTimeout(function() { self.destroy(); }, 2000); }); a_cb(); }); } ... 

La connexion à l'événement de clic sur le symbole "x" s'effectue en appelant fos :: addDomListener, qui ne réinitialise pas les événements connectés lors du changement du parent de l'élément DOM.

Dans le gestionnaire d'événements, nous fermons la fenêtre. Tout d'abord, nous supprimons bien la fenêtre de l'écran en ajoutant la classe CSS "window-hide". Une fois l'animation terminée, nous appelons la méthode fos :: NRender :: Wrapper :: destroy, qui supprime le modèle et l'objet wrapper.

TOUTES LES DEMANDES ÉCRITES, LANCÉES ET REJOINTS !!!

 node application.js 

Site de développement officiel

Lien vers un exemple

Source: https://habr.com/ru/post/fr473154/


All Articles