11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous,
je cherche à instancier un objet à travers un constructeur récupéré d'une variable type string...
Bon... comme ça... ça fait bizarre à dire mais en fait c'est plutôt bête... Trop bête sans doute...
Du coup je ne sais pas si c'est possible.

var maChaine = "test";
var nouvelleInstance = new window[maChaine]();


Car le code ci dessus ne semble pas marcher Smiley ohwell
Modifié par Heillige Leben (04 Apr 2015 - 14:42)
Le code que tu as donné fonctionne bien. Tu dois probablement avoir un problème de scope. Tu n'as pas d'erreur dans la console ?


var test = function() {
  console.log("constructor called");
};

var maChaine = "test";
var nouvelleInstance = new window[maChaine]();

// "constructor called"


Tu peux poster un peu plus de code ?
Bon, je mélange plusieurs technos....

define([
  "underscore",
  "jquery",
  "backbone",
  "../views/maView",
], function(_, $, Backbone, maView) {


    var Router = Backbone.Router.extend({
        routes : {
            "" : "index",
            "projet/:name": "projet"
        },
        projet : function() { 
                ref = "maView";
                console.log(Object.prototype.toString.call(maView));
                console.log(window.ref);
                var projetCourrant = new window[ ref ]();[#red]*[/#]
        }
    });

    return Router;

});

//[object Function]
//maView
//[#red]* Uncaught TypeError: undefined is not a function[/#]


@PapyJP
la notation "entre crochets" permet aussi de récupérer la valeur d'une propriété d'objet. C'est comme la notation pointée mais en plus, la valeur entre crochets peut être une chaine... Là j’essaie sur l'objet window...Enfin normalement...
Modifié par Heillige Leben (04 Apr 2015 - 20:25)
Modérateur
je confirme cela fonctionne bien:


var a = function (){
  alert('salut');
};
var f = 'a';
new window[f]();


je ne sais pas ce que tu essaie de tester avec ça:


console.log(Object.prototype.toString.call(maView));


Mais as-tu testé :


console.log('is in window:', ref in window);

ou juste

maView();
window.maView();

histoire de voir si elle est bien existant au moment de l'éxecution?
Modifié par kustolovic (04 Apr 2015 - 21:29)
Heillige Leben a écrit :

@PapyJP
la notation "entre crochets" permet aussi de récupérer la valeur d'une propriété d'objet. C'est comme la notation pointée mais en plus, la valeur entre crochets peut être une chaine... Là j’essaie sur l'objet window...Enfin normalement...

Exact, je l'utilise également mais je n'ai toujours pas compris ce que tu essaies de faire avec cette commande, j'ai commencé par l'hypothèse la plus simple...
Juste pour ma gouverne, qu'est-ce que tu as l'intention de faire avec cette syntaxe un peu inhabituelle?
Modifié par PapyJP (04 Apr 2015 - 21:59)
console.log(Object.prototype.toString.call(maView));

pour tester si j'ai bien un objet maView.

var projetCourrant = new maView();

à la place de
var projetCourrant = new window[ ref ]();

fonctionne très bien...
Bon... Va savoir... En tout cas c'est pas bloquant.

@PapyJP
La variable ref correspond à la partie de l'url à droite du chemin projet.
Dans les routes du router backbone c'est :name.
En fait l'idée est d'appeler un objet (une vue backbone) qui correspond à l'url (routes : projet/:name du router) plutôt que de faire autant de fonctions que de vues.
Bien sûr je déclare toutes les vues avant.
Heillige Leben a écrit :
console.log(Object.prototype.toString.call(maView));

pour tester si j'ai bien un objet maView.


Avec ça tu testes le type et non le type d'objet.
Heillige Leben a écrit :
Je ne vois pas bien la différence ?


Tu vas récupérer le type "racine" (function, null, string, etc...) mais pas le type de l'objet du genre : c'est un objet "maView".

C'était pour compléter le post de Kusto.

Bref c'est un peu H.S.

Autre H.S. : tu as oublié le var devant la déclaration de "ref".

Est-ce que tu peux montrer comment tu définis ta classe maView et d'où tu l'appelles ?
ok pour le 1, bon en fait je voulais seulement voir si la fonction existait.

Pour ton point 2, effectivement, mais je voulais être sur d'avoir une variable globale... Enfin du moins je pense.

Pour maView

define([
    'jquery',
    'underscore',
    'backbone',
    'TweenMax'
    ], function($, _, Backbone, TweenMax){


    var maView= Backbone.View.extend({
        initialize: function() {
            console.log('init maView');
        }

    });


    return maView;

});


et elle est défini pour le routeur

define([
  "underscore",
  "jquery",
  "backbone",
  "../views/maView",
], function(_, $, Backbone, maView) {


    var Router = Backbone.Router.extend({
        routes : {
            "" : "index",
            "projet/:name": "projet"
        },
        projet : function() { 
                ref = "maView";
                console.log(Object.prototype.toString.call(maView));
                console.log(window.ref);
                var projetCourrant = new window[ ref ]();*
        }
    });

    return Router;

});

Modifié par Heillige Leben (04 Apr 2015 - 23:31)
Modérateur
Ah ben oui fatalement


], function(_, $, Backbone, maView) {


maView ne fait pas partie du namespace global (window), mais est un attribut de la fonction ici définie.
Pour l'éxecuter dans une fonction nommée, il faudra avoir le contexte mais ici tu as une fonction anonyme ce qui rend le problème plus délicat.

des solutions par exemple:


function(_, $, Backbone, maView) {
  this.maView = maView;
  new this['maView']();

  // ou
  var myFuncs = {
    'maView': maView
  }
  new myFuncs['maView']();
}


ou si tu souhaites faire du global:


  // la déclarer en globale par défaut.
  // c'est assez moche et tu n'as plus besoin de la récuperer par AMD ensuite.
  window.maView= Backbone.View.extend({
        initialize: function() {
            console.log('init maView');
        }

    });


un entre deux serait de namespacer tes view:


  window.views.maView= Backbone.View.extend({
        initialize: function() {
            console.log('init maView');
        }

    });

Modifié par kustolovic (05 Apr 2015 - 00:45)
Merci beaucoup,
c'est exactement ça.

Donc au final mon code:


define([
  "underscore",
  "jquery",
  "backbone",
  "../views/maView",
], function(_, $, Backbone, maView) {


    var Router = Backbone.Router.extend({
        maView : maView,
        routes : {
            "" : "index",
            "projet/:name": "projet"
        },
        projet : function() { 
                var that = this;
                that.vueCourante = "maView";               
                that.projetCourant = new that[ that.vueCourant ]();
        }
    });

    return Router;

});