IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Angular Discussion :

Mettre une valeur dans une variable globale à partir d'une fonction anonyme


Sujet :

Angular

  1. #1
    Membre actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 604
    Points : 206
    Points
    206
    Par défaut Mettre une valeur dans une variable globale à partir d'une fonction anonyme
    Bonjour,

    J'ai une variable globale et je voudrais savoir comment mettre une valeur à cette variable dans une fonction anonyme. J'obtiens toujours la valeur undefined

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    export class classDeTest {
     
        varGlob: number;
     
        un() {
            var a = function() {
              var b = function() {
                 // affecter une valeur à varGlob 
              }
            }
            this.deux();
        }
     
        deux() {
            console.log(this.varGlob)
        }
     
    }

  2. #2
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    ton code n'a aucun sens

    _ tes fonctions "un" et "deux" s’appellent mutuellement ce qui donne une boucle sans fin
    _ tu a deux éléments s’appelant "a" le premier est une fonction et le second est une variable présente à l'intérieur de cette fonction
    _ cette variable "a" crée dans la fonction "a" (qui porte le même non) fonctionne comme un les variables de closure, et ta fonction "a) est elle-même une variable-fonction inclue dans un closure.
    => aucun des deux éléments "a" ne peuvent être accessible au-dehors,
    à cela s'ajoute le fait que tu utilise la notation fléché dont l'un des effet est justement d'anonymiser les fonctions quand on les appelles, car l'interpréteur JS les utilise comme un nouvel objet qu'il est le seul à pouvoir adresser.
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  3. #3
    Membre actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 604
    Points : 206
    Points
    206
    Par défaut
    bonjour,
    Excusez moi je me suis trompé au niveau des noms de variables.
    Je voulais faire un petit exemple ou je voulais affecter une valeur à une variable dans ces fonctions là et pouvoir récupérer cette valeur plus tard.

    Je vous met mon code ca va être sans doute plus simple ^^

    ts
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    export class FormulaireComponent implements OnInit 
    {
      selectedFile = null;
     
      public divH: number; 
      public divW: number;
     
      context: CanvasRenderingContext2D;
      @ViewChild("mycanvas") mycanvas;
     
     // Après le choix de l'image
      onFileSelected(event){
     
        let canvas = this.mycanvas.nativeElement;
        let context = canvas.getContext('2d');
        context.clearRect(0, 0, 300, 300);
     
        let self = this;
        // Rendu de l'image sur le canvas
        var render = new FileReader();
        render.onload = function(event: any) {
          var img = new Image()
          img.onload = function() {
            // modif de l'attribut HTML
            canvas.width = img.width;
            canvas.height = img.height;
            // modif. CSS de l'élément <canvas>
            self.divW = img.width;
            self.divH = img.height;
            context.drawImage(img,0,0);
     
          };
          img.src = event.target.result;
        };
        render.readAsDataURL(event.target.files[0])
     
        this.unTest()
     
      }
     
      // Dessine une ligne
      unTest(){
            console.log(this.divW)
      }
    }
    html

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <form>
      <input type="file" (change)="onFileSelected($event)" accept="image/*"> <br><br>
      <canvas #mycanvas width="400" height="250" style="border: 1px solid red;"></canvas>
    </form>

  4. #4
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    Est-ce que tu a vérifié que l'image est bien chargée au moment ou le test s'exécute ?

    et :
    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      public divH: number =0; 
      public divW: number=0;
    histoire de t’assurer que le transpiller fait bien le job et n'anonyse pas ces 2 variables
    avec en plus un
    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    self.divW = img.width;
    console.log ( self.divW,img.width);
    si tu n'a pas déjà fait les vérifs


    sinon, j'utiliserai pluôt: img.naturalHeightet img.naturalWidth
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  5. #5
    Membre actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 604
    Points : 206
    Points
    206
    Par défaut
    Bonjour,

    Pour tester si l'mage est bien chargé j'ai mis if(!img.complete) ... est ca me renvoie que l'image n'est pas chargé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
     
    export class FormulaireComponent implements OnInit 
    {
     
      public divH: number = 0; 
      public divW: number = 0;
     
      selectedFile = null;
      context: CanvasRenderingContext2D;
      @ViewChild("mycanvas") mycanvas;
     
      constructor() { }
      ngOnInit() {}
     
      // Après le choix de l'image
      onFileSelected(event){
     
        let canvas = this.mycanvas.nativeElement;
        let context = canvas.getContext('2d');
        context.clearRect(0, 0, 300, 300);
     
        let self = this;
        // Rendu de l'image sur le canvas
        var render = new FileReader();
        render.onload = function(event: any) {
          var img = new Image()
          img.onload = function() {
            canvas.width = img.width;
            canvas.height = img.height;
            self.divW = img.width;
            self.divH = img.height;
            context.drawImage(img,0,0);
            console.log ("img.onload: " + self.divW + " - naturalW " + img.naturalWidth + " - width " + img.width);
     
          };
     
          img.src = event.target.result;
         //teste si l'image est bien chargé
          if(!img.complete) { console.log("chargé")} else { console.log("pas encore")}
        };
        render.readAsDataURL(event.target.files[0])
     
        this.unTest()
     
      }
     
     
        unTest(){      
          console.log("unTest: " + this.divW)
        }
     
    }
    Résultat dans la console

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unTest: 0
    pas encore 
    img.onload: 381 - naturalW 381 - width 381

  6. #6
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    -- et comment est-ce que tu lie onFileSelected(event){ ?
    -- est-ce qu'au moins tu le bind ?
    parce sinon, le this est reliée à l'élément sur leque l'event c'est produit (le bouton) et non à l'instance de l'objet
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  7. #7
    Membre actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 604
    Points : 206
    Points
    206
    Par défaut
    Vous voulez le code html pour savoir comment s'active onFileSelected(event) ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <form>
      <input type="file" (change)="onFileSelected($event)" accept="image/*"> <br><br>
      <canvas #mycanvas width="400" height="250" style="border: 1px solid red;"></canvas>
    </form>
    comment je fais pour bind dans le html ?

  8. #8
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    ben oui, il est impossible de lier une instance d'objet dans la partie html.

    ça ne peut se faire qu'en javascript et uniquement dans la classe de l'objet en question
    et c'est mieux de passer la valeur de l'id dans le constructeur,
    mais bon, j'imagine qu'il n'y a qu'un seul et unique machin = new FormulaireComponent( 'trucLoaderImage' ); dans ton code... ?

    les balises <form> </form> sont inutiles....

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
     <input type="file" id="trucLoaderImage" accept="image/*" />
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    constructor(ID_Loader)
    {
      document.getElementById(ID_Loader).addEventListener('change', this.onFileSelected(ev).bind(this)  );
    }
    ou justement l'avantage des fonctions fléchées, car elles sont en " Bind " obligatoire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    constructor(ID_Loader)
    {
      document.getElementById(ID_Loader).addEventListener('change', ev=>this.onFileSelected(ev));
    }
    mais si tu veux pouvoir faire un removeEventListener il faut affecter la méthode "bindée" sur une fonction
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  9. #9
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Bonjour,
    le résultat que tu obtiens dans la console te montre pourtant le chemin.

    Il faut utiliser les données lorsqu'elles sont disponibles

    La fonction mise sur le onload de ton image est asynchrone donc exécutée, potentiellement, après ton appel à this.unTest().
    Si tu veux connaître la taille de l'image il te faut par conséquent qu'elle soit chargée. Ton appel à this.unTest() doit donc ce faire dans la fonction dédiée au onload.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    render.onload = function(event: any) {
        var img = new Image()
        img.onload = function() {
            // modif de l'attribut HTML
            canvas.width = img.width;
            canvas.height = img.height;
            // modif. CSS de l'élément <canvas>
            self.divW = img.width;
            self.divH = img.height;
            context.drawImage(img, 0, 0);
            // affichage des dimensions disponibles ICI
            self.unTest();
        };
        img.src = event.target.result;
    };

  10. #10
    Membre actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 604
    Points : 206
    Points
    206
    Par défaut
    Bonjour,

    J'utilise angular 7, je n'appelle pas par moi même FormulaireComponent() dans mon code.
    J'ai donc enlever la variable ID_Loader en tant que paramêtre de constructor()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      constructor() 
      { 
        document.getElementById("trucLoaderImage").addEventListener('change', ev=>this.selection(ev));
      }
    J'obtiens cette erreur:
    ERROR TypeError: "document.getElementById(...) is null"

  11. #11
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    C'est simple, tu ne peux pas lier l'instance de ton objet ailleurs que dans la classe elle-même.
    soit tu la met dans son constructeur, soit dans une méthode dédiée dans cet objet.

    Sinon, comment instancie-tu ton objet ? (c'est une question, pas une figure de rhétorique)

    il y a tout une panoplie de fonction dans JS pour créer ce pointeur getElementBy ID, by tag, by machin et truc

    Si ton interface est généré à la volée par angular, l'intance de ton objet peut arriver avant que l'interface soit créé, bref faut attendre que les 2 soient présent en même temps et tu dois gérer cette synchronisation


    Il y a forcément un moyen pour mettre un "pointeur" vers ce fichu bouton et lui "binder" ton instance sur le "change d'un eventListener.

    PS: et t'aurais du poster directement ta question dans la partie Angular du Forum, déjà qu'a la base il était dans la partie "Général JavaScript" puis déplacé dans la partie TypeScript...
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  12. #12
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    C'est pas bientôt fini ces divagations, c'est du grand n’importe quoi.

    Tu utilises Angular alors laisse le « lier » tes éléments à tes événements ou alors reviens à du JavaScript « vanilla ».

    Ton problème est expliqué au post #9.

  13. #13
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    @NoSmoking,
    non, ton post #9 est complètement à coté de son problème

    en l'état actuel de son code (sans faire de Bind) on à (et en reprenant ton code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    render.onload = function(event: any) {
        var img = new Image()
        img.onload = function() {
            // modif de l'attribut HTML
            canvas.width = img.width;
            canvas.height = img.height;
            // modif. CSS de l'élément <canvas>
     
     console.log("type ="      , self.type );              //  -->   type = file
     console.log("tagName ="   , self.tagName );     //  -->   tagName = INPUT
     console.log("outerHTML =" , self.outerHTML );   //  -->   <input type="file" ...
     
            self.divW = img.width;
            self.divH = img.height;
            context.drawImage(img, 0, 0);
            // affichage des dimensions disponibles ICI
            self.unTest();
        };
        img.src = event.target.result;
    };
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  14. #14
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Si tu le dis, seulement il faut prendre le code dans sa totalité et regarder ce qui se passe dans le template et notamment cette ligne
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    <input type="file" (change)="onFileSelected($event)" accept="image/*">
    Si les déclarations sont correctes cela devrait fonctionner parfaitement.

  15. #15
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    c'est pas une question de voir ou non l'intégralité de son code,
    je l'ai indiqué précédemment...
    Citation Envoyé par psychadelic Voir le message
    le this est relié à l'élément sur lequel l'event c'est produit (le bouton) et non à l'instance de l'objet
    et ça sera toujours comme ça quelle que soit le contexte d'utilisation,
    tant qu'il n'y aura pas de "bind' fait à l'intérieur de l'objet (car lui seul permet d'avoir l'adresse de son propre "this")
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  16. #16
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Si l'on reprend au post #3 le log qu'à obtenu pitchu est le suivant
    Citation Envoyé par pitchu
    Pour tester si l'mage est bien chargé j'ai mis if(!img.complete) ... est ca me renvoie que l'image n'est pas chargé.
    unTest: 0
    pas encore
    img.onload: 381 - naturalW 381 - width 381
    pitchu a simplement mal interprété le log.

    • Ce que montre le console.log() à l'intérieur de l'événement onload de l'image c'est bien produit, ce qui signifie que l'action sur l'<input type="file"> à bien était réalisée, ce qui signifie qu'il y a donc bien eut « bindage » entre l'élément et l'action onFileSelected(event).

    Citation Envoyé par psychadelic
    c'est pas une question de voir ou non l'intégralité de son code,
    Ben si un peu quand même, car je le répète nous sommes dans un « contexte Angular » et à ce titre tu devrais regarder du côté de la documentation : Binding to user input events.

    Fait tourner l'exemple sous Angular et tu te rendras compte que cela fonctionne sous réserve d'apporter les modifications que j'ai signalées.

    Peut être pitchu pourra nous donner son avis.

  17. #17
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    effectivement d'apres cette Doc ça devrait être "bon".

    mais comme je suis comme st tomas, j'aimerai bien qu'il fasse mon test indiqué dans mon post #13, histoire d'être fixé..
    mais j'ai l'impression qu'il nous à tout 2 laissé tomber apres nous avoir baladé (3e partie de forum) avec sa première question imaginaire (et fausse) puis les suivantes ou l'on découvre qu'il s'agit d'un code Angular...
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

Discussions similaires

  1. Réponses: 1
    Dernier message: 01/05/2014, 17h25
  2. Réponses: 21
    Dernier message: 11/04/2012, 09h32
  3. Réponses: 8
    Dernier message: 10/01/2012, 16h44
  4. insertion de valeurs dans un combobox a partir d'une table
    Par FstDsi dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 03/06/2008, 00h01
  5. modifier une valeur dans des variables
    Par bombjack91 dans le forum VB.NET
    Réponses: 3
    Dernier message: 29/06/2007, 08h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo