Un cadre de micro-application raisonnable avec une réutilisation pratique.
el.js est un framework construit sur les modèles Riot.js pour créer des micro-applications.
Les frameworks Web exigent que les développeurs créent la plupart, sinon la totalité, de leurs pages Web pour qu'elles soient des applications Web dynamiques. Cela permet aux développeurs de s'assurer que tout ce qui figure sur leur page Web obéit à un flux de rendu unique, cohérent et prévisible, sur lequel ils peuvent raisonner. Cependant, il existe également de nombreux inconvénients par rapport aux sites Web statiques traditionnels, notamment des systèmes de mise en cache plus complexes, des temps de chargement plus longs et des problèmes de référencement. Les microapplications offrent une solution puissante à ces inconvénients. Au lieu de créer des applications Web monolithiques géantes, créez de petites applications et intégrez-les sur vos pages autrement statiques.
Une micro-application exécute une petite fonctionnalité très limitée qui peut être réutilisée encore et encore. Les micro-applications ne diffèrent pas beaucoup de l'idée des widgets intégrables avant que les frameworks ne deviennent la norme, mais elles diffèrent dans leur exécution en mettant l'accent sur le recours à des frameworks raisonnables et à une réutilisation pratique.
HTML : index.html
< html >
< head >
<!-- Head Content -->
< link rel =" stylesheet " src =" https://cdn.jsdelivr.net/gh/hanzo-io/el-controls/theme.css " />
</ head >
< body >
< my-form >
< div >
< label > Type Your Name </ label >
<!-- bind my-input to parent(my-form).data.name, parent.data is implicit for what is supplied to bind attribute -->
< my-input bind =' name ' />
</ div >
< div >
< span > Your Name Is </ span >
< span > { data.name } </ span >
</ div
</ my-form >
<!-- el.js Library -->
< script src =" https://cdn.jsdelivr.net/gh/hanzo-io/el.js/el.min.js " > </ script >
< script src =" my-script.js " > </ script >
</ body >
</ html >
JS : mon-script.js
// window.El is the global value
// El.Form extends El.View and validates bound El.Inputs
class Form extends El . Form {
constuctor ( ) {
// data contains your state
this . data = {
name : '?' ,
}
// your custom tag name
this . tag = 'my-form'
super ( )
}
}
Form . register ( )
// El.Input extends El.View and binds to updating El.Form values
class Input extends El . Input {
constructor ( ) {
// your custom tag name
this . tag = 'my-input'
// the default this.change function works with all basic html inputs(<input>, <textarea>, ...).
this . html = '<input onkeydown="{ change }" />'
super ( )
}
}
Input . register ( )
El . mount ( '*' )
Ajoutez cette balise au bas de avant vos scripts et dépôts personnalisés et votre fenêtre de référence.El.
< script src =" https://cdn.jsdelivr.net/gh/hanzo-io/el.js/el.min.js " > </ script >
Installer via NPM
npm install el . js -- save
Prend en charge CommonJS
var El = require ' el.js '
ou importations ES6
import El from ' el.js '
Ce type est référencé par El.Form pour stocker les informations utilisées pour valider le champ associé à name .
Nom | Taper | Défaut | Description |
---|---|---|---|
configuration | MiddlewareFunction ou [ MiddlewareFunction ] | indéfini | Ce type stocke la MiddlewareFunction ou les MiddlewareFunctions d'origine utilisées pour créer validate() |
nom | chaîne | '' | Il s'agit du nom d'un champ de la propriété data de El.Form auquel le reste de ce type fait référence. |
réf | Arbre de référence | indéfini | Il s'agit d'un lien vers l'arborescence de données mutable qui peut récupérer la valeur de name en appelant this.ref.get( name ) |
Nom | Taper | Description |
---|---|---|
valider | (Arbre référentiel, chaîne) => Promesse | Cette méthode appelle toutes les MiddlwareFunctions en série à l’aide de promesses. |
Ce type est utilisé pour définir un middleware pour El.Form . Effectuez la validation et la désinfection des entrées avec ces fonctions telles que :
function isRequired ( value ) {
value = value . trim ( )
if ( value && value != '' ) {
return value
}
throw new Error ( 'Required' )
}
Ce type est utilisé en interne à certains endroits pour faciliter le retour des promesses par référence.
Il s'agit de la classe de base pour toutes les classes El. Chaque El.View correspond à une balise personnalisée. Étendez cette classe pour créer vos propres balises personnalisées.
Nom | Taper | Défaut | Description |
---|---|---|---|
css | chaîne | '' | Il s'agit d'une chaîne représentant le CSS de la balise. Il est injecté une fois par classe en bas du tag une fois monté. |
données | Arbre de référence | indéfini | Cette propriété stocke l'état de la balise. |
HTML | chaîne | '' | Il s'agit d'une chaîne représentant le code HTML interne de la balise. |
racine | Élément HTML | indéfini | Cette propriété stocke une référence à la balise de votre page Web à laquelle la vue montée est liée. |
étiqueter | chaîne | '' | Il s'agit du nom de la balise personnalisée. |
Nom | Taper | Description |
---|---|---|
avantInit | () => | Le code ici s'exécute avant l'initialisation de la balise. |
initialisation | () => | Le code ici s'exécute lorsque la balise est initialisée mais avant son montage. Recommandé : si vous devez vous lier au cycle de vie de la balise, faites-le ici. |
calendrierMise à jour | () => Promesse | Cette méthode planifie un appel de mise à jour asynchrone. Il regroupe les appels de mise à jour dans la vue la plus haute s'il existe des vues imbriquées. Il renvoie une promesse pour l'exécution de la mise à jour |
mise à jour | () => | Cette méthode met à jour la balise. Ceci est appelé implicitement après des événements déclenchés à partir d'une page Web. Voir onkeydown dans Un « exemple de formulaire simple » pour un tel cas. Appelez manuellement cette méthode pour mettre à jour la balise. Recommandé - Il est recommandé d'appeler manuellement planningUpdate() à la place pour éviter les cascades de mises à jour synchrones. |
Chaque El.View est un émetteur d'événements. Voir riot.observable pour plus de documentation, http://riotjs.com/api/observable/
Nom | Taper | Description |
---|---|---|
El.View.register | () => | Cela enregistre la balise personnalisée actuelle auprès du moteur de rendu. Appelez-le après avoir défini une balise |
Cette classe est utilisée pour représenter des formulaires ainsi que des micro-applications plus complexes pilotées par les E/S. Cette classe fournit une validation de formulaire commune et une logique de soumission de formulaire.
Nom | Taper | Défaut | Description |
---|---|---|---|
configurations | Objet | indéfini | Fournissez une carte de noms à un MiddlewareFunction ou à un tableau de MiddlewareFunctions . Voir MiddlewareFunction pour plus d’informations. |
entrées | Objet | nul | Chaque élément des configurations est converti en élément dans les entrées . Il n'est pas recommandé de modifier cela directement. |
Nom | Taper | Description |
---|---|---|
initialisation | () => | Le code ici s'exécute lorsque la balise est initialisée mais avant son montage. Appelle initInputs() donc appelez-le manuellement - ou appelez super() dans ES6. Recommandé : si vous devez vous lier au cycle de vie de la balise, faites-le ici. |
entrées d'initialisation | () => | Compilez les configurations et attribuez la structure émise aux inputs . les entrées comme les configurations contiennent des références au champ nommé dans data . |
soumettre | (Événement) => Promesse | Cette méthode déclenche la validation pour chaque champ des données tel que défini dans configs . Cette méthode doit être appelée en tant que gestionnaire/écouteur d’événements. Il appelle submit() si la validation réussit, renvoie une promesse pour le moment où la validation réussit/échoue |
_soumettre | () => | Le code ici s'exécute lorsque le formulaire est validé lors de l'appel submit() |
Il s'agit de la classe de base pour créer des entrées de formulaire et des contrôles IO.
Nom | Taper | Défaut | Description |
---|---|---|---|
lier | chaîne | '' | Cette propriété détermine à quel champ des données du formulaire parent elle est liée. |
chercher | chaîne | '' | Identique à bind , obsolète . |
Message d'erreur | chaîne | '' | Cette propriété est définie sur le premier message d'erreur détecté par la promesse renvoyée par this.input.validate. |
saisir | Type d'entrée | nul | Cette propriété est extraite de la propriété inputs du formulaire parent en fonction de ce que spécifie la liaison de champ des données parent. |
valide | bouffon | FAUX | Cette propriété est utilisée pour déterminer l'état de validation dans lequel se trouve l'entrée. Elle est définie lorsque this.input.validate est appelé, elle n'est définie sur true que si la promesse renvoyée par this.input.validate s'exécute complètement. |
Nom | Taper | Description |
---|---|---|
changement | (Événement) => | Cette méthode met à jour l'entrée puis la valide. Cette méthode doit être appelée par un gestionnaire/écouteur d'événements. |
modifié | () => | Cette méthode est appelée lorsque la promesse renvoyée par this.input.validate s'exécute complètement. |
effacerErreur | () => | Cette méthode définit errorMessage sur '' et est appelée avant validation. |
erreur | (Erreur) => | Cette méthode définit errorMessage et est appelée lorsque la validation échoue. |
obtenirValeur | (Événement) => n'importe quel | Cette méthode obtient la valeur de l'entrée. Par défaut, cette méthode renvoie la valeur target.value de l' Event . |
valider | (PromiseReference?) => Promesse | Cette méthode valide l'entrée, elle renvoie une promesse représentant le succès et l'échec de la validation à la fois par référence (nécessaire en interne) et par valeur. |
Nom | Taper | Description |
---|---|---|
El.scheduleUpdate | () => | Planifiez la mise à jour de toutes les micro-applications de la page. |
Les fonctions de cycle de vie de el.js sont héritées de Riot.js.
el.js utilise des arbres référentiels pour stocker ses données de formulaire.
Implémentez les méthodes get, set, on, once, off à partir du référentiel autour de votre propre structure de données et déposez-les en tant que propriété de données.
Un conteneur est une balise personnalisée qui fournit des méthodes à utiliser pour son modèle interne et dont le contenu peut être entièrement écrasé (contient uniquement le contenu d'une ou plusieurs balises). Un contrôle est un composant qui interagit avec l'utilisateur dans le but d'afficher des informations de manière intéressante ou d'obtenir des entrées telles qu'une entrée, une sélection ou une intégration GoogleMaps.
Au lieu de créer des widgets de manière étroitement couplée, décomposez le widget en conteneurs et en contrôles pour maximiser la réutilisation. Structurez le HTML interne de la manière la plus logique. Ensuite, diffusez votre widget, votre conteneur et vos contrôles terminés à vos utilisateurs afin qu'ils puissent personnaliser le widget en fonction de leurs différents besoins.
En faisant abstraction des éléments de votre interface utilisateur de cette manière, il est beaucoup plus facile pour quelqu'un d'autre de réutiliser et de personnaliser votre code. Voir shop.js pour une implémentation.
Il est préférable d'utiliser un seul magasin d'état de haut niveau pour simplifier l'enregistrement et la restauration de l'état de votre page Web ou de l'ensemble du site Web.
Ceci peut être réalisé en fournissant à tous les conteneurs de niveau supérieur de la page le même champ de données . via l'appel de montage initial
var data = {
state0 : 0 ,
state1 : 1 ,
}
El . mount ( '*' , { data : data } )
Contrairement au rendu Riot normal, el.js permet l'accès implicite aux valeurs sur this.parent et this.parent...parent via l'héritage prototypique du contexte de rendu. Ceci est fait pour éviter de transmettre à plusieurs reprises les mêmes données via des conteneurs imbriqués, car elles sont sujettes aux erreurs et trop verbeuses. Cela facilite également la création de conteneurs et de contrôles.
Passer explicitement la variable data :
< my-container-1 >
< my-container-2 data =' { data } ' >
< my-container-3 data =' { data } ' >
value: { data.value1 }
</ my-container-3 >
< my-container-3 data =' { data } ' >
value: { data.value2 }
</ my-container-3 >
</ my-container-2 >
< my-container-2 data =' { data } ' >
< my-container-3 data =' { data } ' >
value: { data.value3 }
</ my-container-3 >
< my-container-3 data =' { data } ' >
value: { data.value4 }
</ my-container-3 >
</ my-container-2 >
</ my-container-1 >
// El.mount passes data to the top level container of each micro-app
El . mount ( '*' , data : { value1 : 1 , value2 : 2 , value3 : 3 , value4 : 4 } )
Équivaut à référencer implicitement la variable de données.
< my-container-1 >
< my-container-2 >
< my-container-3 >
value: { data.value1 }
</ my-container-3 >
< my-container-3 >
value: { data.value2 }
</ my-container-3 >
</ my-container-2 >
< my-container-2 >
< my-container-3 >
value: { data.value3 }
</ my-container-3 >
< my-container-3 >
value: { data.value4 }
</ my-container-3 >
</ my-container-2 >
</ my-container-1 >
// El.mount passes data to the top level container of each micro-app
El . mount ( '*' , data : { value1 : 1 , value2 : 2 , value3 : 3 , value4 : 4 } )
BSD