Les plats clés
- L'article décrit comment construire une pièce client pour un service de visualisation de la batterie à l'aide de Node.js, qui met à jour l'état de la batterie à intervalles réguliers sans recharger la page. Le client peut faire une pause ou reprendre les mises à jour pour éviter de surcharger le système lorsque les informations ne sont pas nécessaires.
- Les cadres de conception et de déclaratifs réactifs sont utilisés pour mettre à jour automatiquement et efficacement le modèle d'objet de document (DOM) en réponse aux modifications des données. Ceci est réalisé à l'aide de Racactive.js, une bibliothèque qui lie les données aux éléments DOM et met à jour le DOM chaque fois que les données changent.
- L'auteur montre comment utiliser Racactive.js pour créer une visualisation de la batterie, y compris la mise en place d'un mécanisme pour faire une pause / reprendre les mises à jour, et la récupération de données de manière asynchrone à partir d'un service de repos.
- L'article se termine par un appel pour explorer davantage les outils et les concepts discutés, tels que la configuration d'un serveur HTTP à l'aide de Node.js, des API RESTFul, des commandes de terminal OS exécutées sur un serveur Node.js et les bases des frameworks déclaratifs et racactive.js.
Dans la première partie de cette mini-série, nous avons discuté des détails du service que nous construisons et de ce que vous apprendrez. Nous avons ensuite expliqué pourquoi nous avons besoin d'un serveur et pourquoi j'ai choisi pour créer un service RESTful. Tout en discutant de la façon de développer le serveur, j'ai pris l'occasion de discuter de la façon dont vous pouvez identifier le système d'exploitation actuel et également comment utiliser Node.js pour y exécuter des commandes.
Dans cette deuxième et dernière partie de cette série, vous découvrirez comment créer la partie client pour présenter les informations aux utilisateurs de manière agréable. Pour atteindre cet objectif, nous devons mettre à jour l'état de la batterie toutes les x minutes (ou secondes), sans recharger la page. De plus, nous devrions être en mesure de suspendre / reprendre les mises à jour, pour éviter d'inonder notre système lorsque nous n'avons pas besoin des informations, ou même lorsque nous ne regardons pas la page. Pour ce faire, nous allons:
- Planifiez les appels Ajax à notre service backend sur des intervalles de temps réguliers;
- Utilisez un cadre déclaratif qui met à jour le DOM automatiquement et efficacement en réponse aux modifications apportées aux données;
- Utilisez une fonction d'utilité jQuery pour nous faciliter la vie;
- Utilisez de belles images et CSS pour rendre le tableau de bord visuel attrayant (en bonus!).
Design réactif
Discuter des appels de l'Ajax et des asynchrones est certainement hors de portée de cet article (je fournirai quelques liens utiles à la fin de la publication). Pour notre objectif, nous pouvons même les traiter comme des boîtes noires qui nous permettent de demander au serveur des données et d'exécuter une action une fois les données renvoyées.
Prenons plutôt une minute pour discuter de la conception réactive et des cadres déclaratifs.
Une page HTML est par défaut une entité statique. Cela signifie que pour une page HTML pure, le contenu indiqué sur la page reste le même à chaque fois qu'il est rendu dans un navigateur. Cependant, nous savons qu'avec l'utilisation de JavaScript et peut-être des bibliothèques de modèles comme Mustache, nous pouvons les mettre à jour dynamiquement.
Il existe de nombreuses bibliothèques qui aident les développeurs à lier des données aux nœuds DOM. La plupart d'entre eux utilisent JavaScript pour décrire les éléments DOM auxquels les données doivent être traduites et nécessitent des mises à jour de la page à déclencher manuellement (via JavaScript). Ainsi, nous finissons par compter sur la logique de l'application pour décider quand la visualisation doit être mise à jour et les modifications doivent être apportées en réponse aux modifications de données.
Les cadres déclaratifs lient les données aux éléments DOM et mettent automatiquement à mettre à jour le DOM, chaque fois que les données changent. Cette liaison est également fournie à l'aide de modèles dans la présentation (le balisage HTML) plutôt que dans JavaScript.
La valeur ajoutée de ces cadres peut être identifiée en quelques points clés:
- Ils appliquent un plus grand degré de séparation entre le contenu et la présentation. Ceci est réalisé en vous permettant de définir dans la liaison de la couche de présentation pour les données, les gestionnaires d'événements et même la structure des vues (comme pour les objets itératifs et composites, par exemple des tables);
- Ils fournissent un moyen facile de conserver votre modèle de données et votre présentation en synchronisation;
- Ils le font généralement de manière extrêmement efficace, en s'assurant de reflux uniquement le sous-ensemble minimum possible de votre arbre Dom. À cet égard, gardez à l'esprit que le refus et la repeinture sont généralement des goulots d'étranglement pour les applications de navigateur côté client.
racactive.js
Pour Racactive.js, la bibliothèque que nous allons utiliser, la synchronisation entre les données et DOM est obtenue via
objets de conteneur . La bibliothèque crée des objets qui s'enroulent autour des données. Ces objets ont accès aux données, donc chaque fois que vous définissez ou obtenez une propriété, la bibliothèque peut capturer votre action et la diffuser en interne à tous les abonnés.
pratique
Maintenant que nous avons vu à quoi RACVAC.JS est utile, il est temps d'ajouter notre premier modèle de ratification à notre page. Pour ce faire, vous pouvez ajouter une balise de script avec un ID de votre choix n'importe où dans le . Je vous suggère de choisir sagement l'identification car nous en aurons besoin plus tard. Nous devrons également ajouter un attribut type = 'text / racactive':
<span><span><span><script</span> id<span>='meterVizTemplate'</span> type<span>='text/ractive'</span>></span><span><span></script</span>></span></span>
Copier après la connexion
Copier après la connexion
Type = 'Text / Racactive'
n'aurait en fait aucun sens pour votre navigateur, car il ignorera le script à moins que vous ajoutiez également le script de Racactive à votre page:
<span><span><span><script</span> src<span>='http://cdn.ractivejs.org/latest/ractive.js'</span>></span><span><span></script</span>></span></span>
Copier après la connexion
Copier après la connexion
Désormais, à l'intérieur du script ROCTIVE, vous pouvez ajouter des balises HTML et des variables de modèle et des conditionnels / boucles. RACTIVE.JS s'occupera d'évaluer tout dans les groupes {{}}.
<span><span><span><script</span> id<span>='meterVizTemplate'</span> type<span>='text/ractive'</span>></span><span>
</span></span><span><span> <span>{{#batteryState}}
</span></span></span><span><span> <span><br>
</span></span></span><span><span> <span><div class='battery-div'>
</span></span></span><span><span> <span><div class='battery-shell'>
</span></span></span><span><span> <span><div class='battery-percent-text'>{{batteryPercent.toFixed(1) + '%'}}</div>
</span></span></span><span><span> <span></div>
</span></span></span><span><span> <span><div class='battery-level'>
</span></span></span><span><span> <span><div class='battery-mask' style="width:{{(100 - batteryPercent) + '%'}};">
</span></span></span><span><span> <span></div>
</span></span></span><span><span> <span></div>
</span></span></span><span><span> <span>{{#batteryCharging}}
</span></span></span><span><span> <span><div class='battery-plug' intro-outro='fade:1000'></div>
</span></span></span><span><span> <span>{{/batteryCharging}}
</span></span></span><span><span> <span>{{#batteryPercent <= batteryRedThreshold}}
</span></span></span><span><span> <span><div class='battery-warning' intro-outro='fade:1000'></div>
</span></span></span><span><span> <span>{{/batteryLife}}
</span></span></span><span><span> <span></div>
</span></span></span><span><span> <span><br>
</span></span></span><span><span> <span><br>
</span></span></span><span><span> <span><span class='key'>Battery state:</span> <span class='value {{batteryStateClass(batteryState)}}'>{{batteryState}}</span>
</span></span></span><span><span> <span><br>
</span></span></span><span><span> <span>{{#batteryLife}}
</span></span></span><span><span> <span><span class='key'>Time to empty:</span> <span class='value {{batteryLifeClass(batteryPercent)}}'>{{batteryLife}}</span>
</span></span></span><span><span> <span>{{/batteryLife}}
</span></span></span><span><span> <span>{{/batteryState}}
</span></span></span><span><span> <span>{{^batteryState}}
</span></span></span><span><span> <span><br>
</span></span></span><span><span> <span>LOADING...
</span></span></span><span><span> <span>{{/batteryState}}
</span></span></span><span><span></span><span><span></script</span>></span></span>
Copier après la connexion
Copier après la connexion
Dans l'exemple ci-dessus, vous pouvez voir:
- Variables: {{Batterystate}}
- conditionnels: {{#batterystate}}
- Invocations de la fonction: {{BatterystateClass (batterie)}}
Pour que ces choses fonctionnent, nous devons ajouter une certaine liaison en JavaScript. Pour ce faire, nous devons créer un nouvel objet Racactive.js:
<span><span><span><script</span> id<span>='meterVizTemplate'</span> type<span>='text/ractive'</span>></span><span><span></script</span>></span></span>
Copier après la connexion
Copier après la connexion
Les options que nous transmettons au constructeur sont assez importantes. Tout d'abord, El doit correspondre à l'ID d'un élément DOM à l'intérieur de laquelle Racactive.js rendra le modèle. Dans ce cas, nous devons ajouter un div pour sortir la page HTML:
<span><span><span><script</span> src<span>='http://cdn.ractivejs.org/latest/ractive.js'</span>></span><span><span></script</span>></span></span>
Copier après la connexion
Copier après la connexion
Le point où vous insérez cette balise est importante. Ce sera l'élément
Parent pour tous les éléments rendus par système de modèles Racactive.js. Le deuxième paramètre important dont vous devez faire attention est le modèle. Sa valeur devra correspondre à l'ID du script texte / ratifiant sur votre page. Enfin, nous attribuons aux données d'un objet dont les clés sont des noms de variables que nous référentes dans notre modèle ou les fonctions que nous appelons.
Avec Racactive.js, nous pouvons même définir des événements personnalisés auxquels la bibliothèque répondra:
<span><span><span><script</span> id<span>='meterVizTemplate'</span> type<span>='text/ractive'</span>></span><span>
</span></span><span><span> <span>{{#batteryState}}
</span></span></span><span><span> <span><br>
</span></span></span><span><span> <span><div class='battery-div'>
</span></span></span><span><span> <span><div class='battery-shell'>
</span></span></span><span><span> <span><div class='battery-percent-text'>{{batteryPercent.toFixed(1) + '%'}}</div>
</span></span></span><span><span> <span></div>
</span></span></span><span><span> <span><div class='battery-level'>
</span></span></span><span><span> <span><div class='battery-mask' style="width:{{(100 - batteryPercent) + '%'}};">
</span></span></span><span><span> <span></div>
</span></span></span><span><span> <span></div>
</span></span></span><span><span> <span>{{#batteryCharging}}
</span></span></span><span><span> <span><div class='battery-plug' intro-outro='fade:1000'></div>
</span></span></span><span><span> <span>{{/batteryCharging}}
</span></span></span><span><span> <span>{{#batteryPercent <= batteryRedThreshold}}
</span></span></span><span><span> <span><div class='battery-warning' intro-outro='fade:1000'></div>
</span></span></span><span><span> <span>{{/batteryLife}}
</span></span></span><span><span> <span></div>
</span></span></span><span><span> <span><br>
</span></span></span><span><span> <span><br>
</span></span></span><span><span> <span><span class='key'>Battery state:</span> <span class='value {{batteryStateClass(batteryState)}}'>{{batteryState}}</span>
</span></span></span><span><span> <span><br>
</span></span></span><span><span> <span>{{#batteryLife}}
</span></span></span><span><span> <span><span class='key'>Time to empty:</span> <span class='value {{batteryLifeClass(batteryPercent)}}'>{{batteryLife}}</span>
</span></span></span><span><span> <span>{{/batteryLife}}
</span></span></span><span><span> <span>{{/batteryState}}
</span></span></span><span><span> <span>{{^batteryState}}
</span></span></span><span><span> <span><br>
</span></span></span><span><span> <span>LOADING...
</span></span></span><span><span> <span>{{/batteryState}}
</span></span></span><span><span></span><span><span></script</span>></span></span>
Copier après la connexion
Copier après la connexion
En quelques lignes, nous avons mis en place un mécanisme pour faire une pause / reprendre nos mises à jour. Cependant, nous devons encore définir le UpdateBatteryStatus ()
fonction.
récupérer de manière asynchrone les données
Comme promis, c'est ici une fonction qui s'occupe de récupérer les données de notre service de repos. En utilisant l'objet différé jQuery, nous avons configuré un rappel pour être invoqué dès que certaines données sont reçues du serveur. Étant donné que nous utilisons également Racactive.js à l'intérieur de ce rappel, nous n'aurons pas à passer par la logique de la façon dont nous avons mis à jour la couche de présentation. En fait, nous mettons simplement à jour la valeur des variables utilisées dans le script de modèle, et Racactive.js s'occupera de tout.
Ce que je viens de décrire est mis en œuvre par le code indiqué ci-dessous:
ractive <span>= new Ractive({
</span> <span>el: 'panels',
</span> <span>template: '#meterVizTemplate',
</span> <span>data: {
</span> <span>// Percentage at which the battery goes to 'red' zone (export for Ractive templates)
</span> <span>batteryRedThreshold: BATTERY_RED_THRESHOLD,
</span> <span>// Percentage at which the battery enters 'yellow' zone (export for Ractive templates)
</span> <span>batteryYellowThreshold: BATTERY_YELLOW_THRESHOLD,
</span> <span>// The capacity of the battery, in percentage. Initially empty
</span> <span>batteryPercent: NaN,
</span> <span>// How much more time can the battery last?
</span> <span>batteryLife: "",
</span> <span>// True <=> the update daemon for the battery has been paused
</span> <span>batteryPaused: false,
</span> <span>// True <=> the update daemon for the battery has reported an error at its last try
</span> <span>batteryUpdateError: false,
</span> <span>// Is the battery connected to power?
</span> <span>batteryCharging: false,
</span> <span>batteryStateClass: function (state) {
</span> <span>return state === 'discharging' ? BATTERY_RED_CLASS : BATTERY_GREEN_CLASS;
</span> <span>},
</span> <span>batteryLifeClass: function (percent) {
</span> <span>return percent <= BATTERY_RED_THRESHOLD ? BATTERY_RED_CLASS : (percent <= BATTERY_YELLOW_THRESHOLD ? BATTERY_YELLOW_CLASS : BATTERY_GREEN_CLASS);
</span> <span>}
</span> <span>}
</span><span>});</span>
Copier après la connexion
Mettre tout cela ensemble
Il y a, bien sûr, un câblage supplémentaire à mettre en place pour que tout cela fonctionne ensemble. Nous avons complètement sauté la conception du tableau de bord UX. Cela dépend en fin de compte de vous, une fois que vous obtenez comment le faire fonctionner avec le système de modèles! Par exemple, à quel point serait-il cool si nous pouvions avoir le pourcentage de charge affiché à la fois en texte et visuellement avec un indicateur de puissance cool, en utilisant des images et des animations? Avec Racactive.js, ce n'est pas si difficile! Jetez un œil au résultat final:

Si vous souhaitez inspecter le code, vous pouvez à nouveau le retrouver sur GitHub.
Conclusions
Notre tableau de bord de batterie multiplateforme devrait être prêt à partir maintenant. Mais cela devrait être un point de départ plutôt qu'un résultat final, et les points importants que j'espère que vous avez appris en cours de route sont:
- Comment configurer un serveur HTTP à l'aide de node.js
- API RESTFul
- Comment exécuter les commandes de terminal OS sur un serveur Node.js
- Bases des cadres déclaratifs et ratic.js en particulier
Si vous voulez passer au niveau supérieur, mon conseil est de commencer à expérimenter sur ces outils et à creuser le filet pour approfondir les connaissances dans ces domaines. Si vous souhaitez approfondir les sujets abordés dans cet article, je vous suggère fortement de jeter un œil à ces bonnes ressources:
- Styles architecturaux et conception d'architectures logicielles basées sur le réseau
- Lignes directrices pour créer une API RESTful
- Quels sont les avantages / inconvénients de l'utilisation de l'API REST sur les bibliothèques natives?
- Modèle du modèle Modèle
- Demandes asynchrones en javascript
- Crockford sur Javascript - Episode IV: La métamorphose de l'Ajax - Great Insight, comme d'habitude, plus une histoire super drôle sur les origines du terme Ajax, en bonus!
- jQuery $ .getjson Méthode
- Tutoriel RacactiveJS
Questions fréquemment posées (FAQ) sur la création d'une visualisation de la batterie à l'aide du client Node.js
Comment puis-je obtenir l'état de la batterie à l'aide de JavaScript?
Pour obtenir l'état de la batterie à l'aide de JavaScript, vous pouvez utiliser l'API d'état de la batterie. Cette API fournit des informations sur le niveau de charge de la batterie du système et vous permet d'être informé par des événements qui sont envoyés lorsque le niveau de la batterie ou l'état de charge change. Voici un exemple simple de la façon de l'utiliser:
Navigator.getBattery (). Puis (fonction (batterie) {
console.log ("Niveau de la batterie:" Battery.Level * 100 "%" );
});
Ce code enregistrera le niveau actuel de la batterie à la console.
Quelle est la méthode Navigator.getBattery?
La méthode Navigator.getBattery fait partie de l'API d'état de la batterie. Il renvoie une promesse qui se résout à un objet BatteryManager, qui fournit des informations sur le niveau de charge de la batterie du système et vous permet d'être notifié par des événements qui sont envoyés lorsque le niveau de la batterie ou l'état de charge change.
Comment puis-je visualiser le Données d'état de la batterie?
Pour visualiser les données d'état de la batterie, vous pouvez utiliser n'importe quelle bibliothèque de cartes JavaScript, telles que chart.js ou d3.js. Ces bibliothèques vous permettent de créer différents types de graphiques et de graphiques à partir de vos données. Vous pouvez également utiliser HTML et CSS pour créer une barre ou un graphique à tarte simple.
Puis-je obtenir l'état de la batterie sur tous les appareils?
L'API d'état de la batterie est prise en charge par la plupart des navigateurs modernes, mais pas tous. Il convient également de noter que certains appareils, tels que les ordinateurs de bureau, peuvent ne pas fournir d'informations précises ou aucune information d'état de la batterie.
Comment puis-je gérer les modifications de l'état de la batterie?
Vous pouvez gérer les modifications d'état de la batterie en ajoutant des auditeurs d'événements à l'objet BatteryManager. L'API d'état de la batterie propose plusieurs événements, tels que «Chargingchange», «Levelchange», «ChargingtimeChange» et «DischargingtimeChange». Voici un exemple de la façon d'utiliser ces événements:
Navigator.getBattery (). Puis (fonction (batterie) {
batterie.addeventListener ('NIVLEACHANGE', function () {
console. Log ("Niveau de la batterie:" Battery.level * 100 "%");
});
});
Ce code enregistrera le nouveau niveau de batterie au Console chaque fois que le niveau de la batterie change.
Comment puis-je utiliser Node.js pour obtenir l'état de la batterie?
Node.js n'a pas de moyen intégré d'obtenir l'état de la batterie. Cependant, vous pouvez utiliser un processus enfant pour exécuter une commande système qui obtient l'état de la batterie, puis analyser la sortie. La commande spécifique dépend de votre système d'exploitation.
Puis-je obtenir l'état de la batterie sans autorisation de l'utilisateur?
Oui, l'API d'état de la batterie ne nécessite aucune autorisation de l'utilisateur à utiliser. Cependant, c'est toujours une bonne pratique pour informer vos utilisateurs si vous collectez des données sur leur système.
Quelle est la précision du niveau de batterie fourni par l'API d'état de la batterie?
Le niveau de batterie fourni par l'API d'état de la batterie est un nombre entre 0,0 et 1,0, représentant le niveau de batterie actuel comme une fraction de la charge complète. La précision de cette valeur dépend de l'appareil et de sa batterie.
Puis-je obtenir l'état de la batterie chez un travailleur Web?
Oui, l'API d'état de la batterie peut être utilisé dans un travailleur Web. Cependant, gardez à l'esprit que tous les navigateurs ne prennent pas en charge les travailleurs Web, et tous les navigateurs qui prennent en charge les travailleurs Web ne prennent pas en charge l'API d'état de la batterie dans un travailleur Web.
Que puis-je faire si l'API d'état de la batterie n'est pas pris en charge?
Si l'API d'état de la batterie n'est pas prise en charge, vous ne pouvez pas faire grand-chose pour obtenir l'état de la batterie. Vous pouvez utiliser la détection des fonctionnalités pour vérifier si l'API est prise en charge et fournir une fonctionnalité alternative ou un message à l'utilisateur si ce n'est pas le cas.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!