Partage
  • Partager sur Facebook
  • Partager sur Twitter

CountDown dans une boucle

meteorjs, countdown jquery, blaze template

Sujet résolu
Anonyme
    18 avril 2018 à 10:52:41

    Bonjour à tous,

    Je remercie avant tout, les personnes qui prendront le temps de répondre à ce sujet et m'aider à y voir plus clair.

    Je développe actuellement une application web temps réel à l'aide de MeteorJS. Pour ceux qui ne connaissent pas, il répond tout à fait à mes besoins étant donné que meteorJs fonctionne de base en temps réel avec MongoDB et "NodeJs"; https://www.meteor.com/.

    Voilà, je décide de m'attaquer à la partie countDown, c'est à dire, afficher un temps qui à partir d'une date ou/et une heure effectue un décompte. Pour cela, je décide d'utiliser un plugin déjà tout fait, jquery.countdown trouvable ici : http://hilios.github.io/jQuery.countdown/

    Tout content, je me lance dans l'écriture du code ce qui donne ceci :

                <table class="horaire-arret">
                    <tbody>
                        <tr>
                            <th>Ligne</th>
                            <th>Destination</th>
                            <th>Départ dans</th>
                        </tr>
                        {{#each depart}}
                        <tr>
                            <td><img src="/images/picto/{{numero_vehicule}}.jpg" alt="ligne"></td>
                            <td>{{nom_destination}}</td>
                            <td data-countdown="2019/01/01"></td>
                        </tr>
                        {{/each}}
                    </tbody>
                </table>

    Et le JS :

    <script type="text/javascript">
    $( document ).ready(function() {
      $('td[data-countdown]').each(function () {
      let $this = $(this), finalDate = $(this).data('countdown');
      $this.countdown(finalDate, function (event) {
            $this.html(event.strftime('%M min'));
        });
      });
    });
    </script>

    Mais cela ne fonctionne pas du tout ! Pourtant, en dehors du each (boucle avec le template Blaze), ça fonctionne bien... j'ai tenté de comprendre le pourquoi du comment afin d'arriver à une solution mais rien y fait, quelqu'un aurait-il compris le problème (peut-être que le code js se li avant que le each s’exécute totalement ?) ?

    Merci encore une fois, à ceux qui prendront la peine de me répondre.

    Edite : C'est bien le problème soupçonné à la fin de mon texte, le each ne se charge pas assez vite et le js s'exécute avant la fin de ce dernier.

    -
    Edité par Anonyme 18 avril 2018 à 11:55:02

    • Partager sur Facebook
    • Partager sur Twitter
      18 avril 2018 à 12:36:10

      Salut,

      Ton template n'est pas encore chargé alors que ton script se lance.

      Tu devrais faire ton js dans un event du templating Blaze

      http://blazejs.org/api/templates.html#Template-onRendered

      -
      Edité par mohzah 18 avril 2018 à 12:37:26

      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        18 avril 2018 à 13:18:09

        Bonjour Mohzah,

        merci de ta réponse, mon collègue et moi même avons déjà tenté cette solution, mais on revient toujours au même problème, le js s’exécute bien avant le each.

        Pour donner plus de détail j'ai :

        Un fichier horaire.html qui contient mon code html et du code blaze dans un tableau (code fournit précédemment).

        Un fichier horaire.js qui contient un template.horaire.helpers qui me renvoi les data dont j'ai besoin :

        import './horaire.html';
        
        Meteor.subscribe('depart');
        
        Template.horaire.helpers({
            depart: function() {
                return Depart.find({}).fetch();
            }
        });

        Dans le fichier horaire.js j'ai ajouté le template.horaire.Rendered et ajouté mon code JS comme ceci :

        import './horaire.html';
        
        Meteor.subscribe('depart');
        
        Template.horaire.helpers({
            depart: function() {
                return Depart.find({}).fetch();
            }
        });
        
        Template.horaire.onRendered(function () {
            $('td[data-countdown]').each(function () {
                let $this = $(this),
                    finalDate = $(this).data('countdown');
                $this.countdown(finalDate, function (event) {
                    $this.html(event.strftime('%M min'));
                });
            });
        });

        Et le résultat et que rien ne s'affiche, je m'y prends sûrement mal, je débute entièrement sur meteorJS, j'utilise l'architecture suivante :

        - client

        -- compatibility

        -- lib

        -- stylesheets

        - imports

        -- api

        -- modules

        -- startup

        --- both

        --- client

        --- server

        -- ui

        --- components

        --- layouts

        --- less

        --- pages

        - private

        - public

        - server


        Mon fichier principal client se trouve dans client/main.js qui importe les fichiers du dossier both et client (import '/imports/startup/both';..).

        Le fichier horaire.html se trouve dans imports/ui/pages/ et de même pour mon fichier horaire.js

        -
        Edité par Anonyme 18 avril 2018 à 13:23:50

        • Partager sur Facebook
        • Partager sur Twitter
          18 avril 2018 à 14:51:08

          Tu ne reçois aucune erreur dans ta console?

          Quand tu dis rien ne s'affiche tu pourrait être plus précis ?

          -
          Edité par mohzah 18 avril 2018 à 14:51:58

          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            18 avril 2018 à 15:14:17

            Aucune erreur. Quand je dis qu'il n'y a rien, j'entends par là que le code Jquery n'ajoute pas la date entre les

            <td data-countdown="2019/01/01"></td>, la colonne depart de mon tableau reste vide. Par contre si je rajoute un setTimeOut de 3 secondes par exemple sur mon code Jquery, ça fonctionne.

            -
            Edité par Anonyme 18 avril 2018 à 15:20:22

            • Partager sur Facebook
            • Partager sur Twitter
              18 avril 2018 à 16:17:39

              C'est ton onRendered qui ne fonctionne pas. Tu met bien une balise portant le nom de template " horaire " au tour de ton tableau ?

              <template name="horaire">
               <table class="horaire-arret">
                  <tbody>
                      <tr>
                          <th>Ligne</th>
                          <th>Destination</th>
                          <th>Départ dans</th>
                      </tr>
                      {{#each depart}}
                      <tr>
                          <td><img src="/images/picto/{{numero_vehicule}}.jpg" alt="ligne"></td>
                          <td>{{nom_destination}}</td>
                          <td data-countdown="2019/01/01"></td>
                      </tr>
                      {{/each}}
                  </tbody>
              </table>
              </template>



              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                18 avril 2018 à 17:37:44

                Oui, le nom du template est bien mis, le onRendered fonctionne bien car lorsque je fais un console.log('lol'); il s'affiche correctement, par contre, lorsque je mets ce même console.log('lol') dans mon code jquery comme ceci :

                Template.horaire.onRendered(function () {
                  $('td[data-countdown]').each(function () {
                    console.log('lol');
                    let $this = $(this),
                    finalDate = $(this).data('countdown');
                    $this.countdown(finalDate, function (event) {
                        $this.html(event.strftime('%M min'));
                    });
                  });
                });

                rien ! Ce qui signifie qu'il ne détecte aucune balise avec comme paramètre data-countdown, ce qui revient au même problème, le code jquery est exécuté bien avant le {{#each depart}}, pourtant, lorsque je mets un <script>console.log('horaire.html');</script> et que je laisse mon autre console.log dans mon onRendered du fichier horaire.js, le console.log de horaire.html s'affiche en premier et ensuite le lol en second ce qui signifie que c'est bien horaire.html qui est exécuté avant mon horaire.js (c'est ce qui est de toute manière indiqué dans le fonctionnement de meteorjs) et pourtant rien. Et je me répétè mais quand je mets setTimeOut de quelques secondes sur mon code jquery ça fonctionne et je ne veux pas de cette solution, ce n'est pas propre. :(

                Voici le code entier de horaire.html :

                <template name="horaire">
                    <div class="body">
                        <div class="grid">
                            <table class="horaire-arret">
                                <tbody>
                                <tr>
                                    <th>Ligne</th>
                                    <th>Destination</th>
                                    <th>Départ dans</th>
                                </tr>
                                {{#each depart }}
                                <tr>
                                    <td><img src="/images/picto/{{numero_vehicule}}.jpg" alt="ligne"></td>
                                    <td>{{nom_destination}}</td>
                                    <td data-countdown="2019/01/01"></td>
                                </tr>
                                {{/each}}
                                </tbody>
                            </table>
                            <div class="infos-trafic">
                                <div class="head-trafic">
                                    <h1><img src="/images/picto/picto-trafic-jaune.png" alt="Alerte">INFOS TRAFIC<img src="/images/picto/picto-trafic-jaune.png" alt="Alerte"></h1>
                                </div>
                                <div class="body-trafic">
                                    <p><img src="/images/picto/11.jpg" alt="11"> En raison de fortes manifestations, un retard de 5 minutes est à prévoir.</p>
                                    <p><img src="/images/picto/20.jpg" alt="20"> En raison de fortes manifestations, un retard de 5 minutes est à prévoir.</p>
                                    <p><img src="/images/picto/11.jpg" alt="11"> En raison de fortes manifestations, un retard de 5 minutes est à prévoir.</p>
                                    <p><img src="/images/picto/11.jpg" alt="11"> En raison de fortes manifestations, un retard de 5 minutes est à prévoir.</p>
                                    <p><img src="/images/picto/11.jpg" alt="11"> En raison de fortes manifestations, un retard de 5 minutes est à prévoir.</p>
                                </div>
                            </div>
                        </div>
                        <div class="pub">
                            <p>PUBLICITE FORMAT 1830 (970) X 250px</p>
                        </div>
                    </div>
                </template>

                Et le horaire.js :

                import './horaire.html';
                
                Meteor.subscribe('depart');
                
                Template.horaire.helpers({
                    depart: () => {
                        return Depart.find();
                    }
                });
                
                Template.horaire.onRendered(() => {
                        this.$('td[data-countdown]').each(() => {
                            let $this = $(this),
                                finalDate = $(this).data('countdown');
                            $this.countdown(finalDate, (event) => {
                                $this.html(event.strftime('%M min'));
                            });
                        });
                });

                Je mets aussi le code du subscribe qui est dans un fichier nommé depart.js situé dans imports/startup/server/(je ne renvois pas encore toutes les données que j'utiliserai, mais ça importe peu dans la résolution du problème) :

                Meteor.publish('depart', function(){
                  return Depart.find({}, {fields: {'nom_arret':1, 'nom_destination':1, 'numero_vehicule':1}});
                });
                


                Et je te remercie énormément de prendre tout ce temps pour me répondre ! Il est vrai que meteorjs est encore jeune et trouver de l'aide c'est assez compliqué.

                -
                Edité par Anonyme 18 avril 2018 à 17:48:51

                • Partager sur Facebook
                • Partager sur Twitter
                  18 avril 2018 à 20:20:18

                  Ok, à mon avis ton subscribe('depart') qui prend son temps. 

                  https://guide.meteor.com/data-loading.html#readiness

                  Sur cette page ils expliquent qu'une subscription n'enverra pas les données directement , il y a un laps de temps pendant le subscribe et l'envoi des données au client.

                  Et qu'il y a un moyen de savoir quand est-ce que les données sont bien arrivées , subscribe() renvoi un handle avec l’état du subscribe :

                  const handle = Meteor.subscribe('depart');
                  Tracker.autorun(() => {
                    const isReady = handle.ready();
                    console.log(`Handle is ${isReady ? 'ready' : 'not ready'}`);  
                  });

                  Plus loin j'ai trouvé ceci :

                  https://guide.meteor.com/ui-ux.html#subscription-readiness

                  Tu peux t'assurer coté client que toutes les subscription sont ready et afficher un loader dans le cas contraire comme dans l'exemple :

                  {{#if Template.subscriptionsReady}}
                    {{> Template.dynamic template=main}}
                  {{else}}
                    {{> App_loading}}
                  {{/if}}



                   De rien , pour être franc je n'ai jamais utilisé MeteorJS.

                  -
                  Edité par mohzah 18 avril 2018 à 20:26:26

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    18 avril 2018 à 21:58:25

                    ça marche, je vais voir de ce côté là !

                    En attendant, si y-a d'autres réponses utiles à apporter n'hésitez pas :magicien:

                    • Partager sur Facebook
                    • Partager sur Twitter
                      19 avril 2018 à 0:05:00

                      Puis-je squatter pour connaitre votre avis critique sur Meteor ?
                      Les posts sur le sujet ne sont pas si frequents :)

                      T.

                      -
                      Edité par Tracker 19 avril 2018 à 0:06:20

                      • Partager sur Facebook
                      • Partager sur Twitter
                        19 avril 2018 à 11:22:58

                        Bonjour,

                        MeteorJS est assez particulier, le fait qu'il fonctionne directement en temps réel sans avoir rien à configurer c'est déjà des heures gagnées, il suffit de taper 2/3 commandes et meteorJS est opérationnel pour le fonctionnement temps réel.

                        La structure fournie de base n'est pas très utilisable (sauf très petit projet), il faudra donc lire la documentation de MeteorJs (seulement disponible en EN) afin d'avoir une structure qui convient mieux pour un moyen et grand projet.

                        Il faudra toutefois  faire attention à bien supprimer certains modules que MeteorJS intègre par défaut qui sont utiles (et encore c'est un fort mort) pour le développement seulement, ils créent une faille de type sql injection (on peut exécuter des requêtes mongodb depuis le client).

                        Aussi, on ne peut malheureusement pas utiliser une autre base de données que MongoDB à l'heure actuelle, apparemment il est prévu dans le temps de pouvoir passer à d'autres SGBD, mais pour le moment, si on change de SGBD le fonctionnement temps réel n'existera tout simplement plus :-°, il existe des alternatives non officielles mais ça crée des failles de type sql injection.

                        La communauté autour de MeteorJS n'est pas très grande comparé à d'autres framework, bien qu'on arrive quand même à avoir des réponses sur le forum officiel MeteorJS, je pense que les connaissances sur ce framework sont encore assez minimes (on dit souvent que sa communauté est grande et que de grands développeurs travaillent sur MeteorJS, mais ce n'est pour l'instant pas mon ressenti).

                        Ce qui est aussi pratique avec MeteorJS, c'est que l'on peut déployer son application en version mobile (je n'ai pas encore testé cette fonctionnalité mais ça à l'air cool).

                        Niveau tutoriel, on en a très peu en français et aucun (à ma connaissance) de complet, par contre en anglais il y en a pas mal mais la plupart datent d'un an minimum (youtube compris), il faut avoir du temps et de la persévérance pour se lancer sur l'apprentissage de ce framework et surtout savoir se débrouiller tout seul la plupart du temps avec ce qu'on a et ce qu'on sait.

                        Finalement, pour tenter MeteorJS, il faut être sûr premièrement que le SGBD pour le projet requière du NoSQL et que MongoDB est le meilleur choix, ensuite, il faut avoir un minimum de connaissance en anglais, sinon je vous raconte pas la galère !

                        Cet avis est basé sur une petite expérience du Framework, il est très puissant quand on sait le manipuler et on peut faire de très belles applis très rapidement si les connaissances du Framework sont présentes !

                        Personnellement, je le recommande, malgré les points négatifs énumérés ci-dessus MeteorJS reste assez simple et flexible, je n'ai pas fait le tour de ce que propose MeteorJS (ça me prendrait trop de temps) mais il est très puissant et très efficace pour créer des applications en temps réel rapidement.

                        Mon sujet sur le forum MeteorJS si ça intéresse des personnes : https://forums.meteor.com/t/meteorjs-cant-use-countdown-in-each/43288


                        PS : J'ai retrouvé mon compte principal OpenClassRooms ;)

                        -------------------------

                        Bonjour,

                        je reviens vers vous pour signaler que le problème est résolu !!

                        Vous trouverez toute la solution ici : https://forums.meteor.com/t/meteorjs-cant-use-countdown-in-each/43288/4

                        Merci tout le monde et bon dev ! ;)

                        -
                        Edité par S@yf 19 avril 2018 à 14:19:35

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Un cerveau c'est bien, plusieurs c'est mieux !

                        CountDown dans une boucle

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                        • Editeur
                        • Markdown