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

Ext JS / Sencha Discussion :

MVC et App multi-modules


Sujet :

Ext JS / Sencha

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut MVC et App multi-modules
    Bonjour.

    cela fait quelques temps que je me pose une question sur MVC dans Sencha.

    Comment définir une appli MVC qui comporte un grand nombre de controlleur sans tout charger au lancement de l'appli ?

    telque sencha l'a défini une Appli MVC déclare ses controlleurs qui eux même déclarent les vues, les modèles et les datastores qu'ils utilisent.

    du coup lorsqu'on lance l'appli les requires en cascade chargent tout le code.
    sur une petite appli ou sur une appli sur internet c'est peut être mieux ainsi.

    mais sur une grosse appli sur un intranet on a plus intérêt à ne charger que le necéssaire et le reste venant en fonction des besoins.

    le problème est alors le suivant.
    ne pas déclarer les controlleurs systématiquement et permettre de les charger au besoin.

    pour résoudre ce pb de façon cohérente et sans avoir trop de boulot à faire je suis partit de l'exemple descktop fourni par sencha.

    c'est typiquement le genre de chose ou on n'a pas envie que toutes les "application" présente sur le bureau virtuel soient chargé au démarrage.

    le bureau est fait de modules, chaque module est en soit une mini appli. j'ai d'abord pensé en faire de vrais applies MVC sandboxé. mais cette approche n'était pas généralisable à autre chose qu'un bureau.
    de plus le bureau lui-même n'était pas MVC.

    j'ai donc regardé comment il fonctionnait et je suis partie de l'idée d'avoir une appli MVC qui suporte la notion de module comme le bureau. au démarrage l'appli charge les modules mais ne les exécute pas.
    les controlleurs des modules étant chargé lors de leur première exécution.

    la methode Ext.Application est particulièrement hermétique et je suis partie de la classe qu'elle instancie. pour définir ce qui serait le ceur de mon système.
    Code javascript : 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
     
    Ext.define('Ext.ux.desktop.System', {
        extend: 'Ext.app.Application',
     
        constructor: function() {
        	var config = arguments[0]||{name: 'MySys'};
        	var modules = Ext.Array.from(config.modules) || [];
        	config.requires = Ext.Array.from(config.requires) || [];
     
        	config.modFolder = config.modFolder || 'modules';
        	config.desktopClass = config.name + '.module.' + config.desktopClass || config.name + '.module.Desktop';
     
        	Ext.Loader.setPath(config.name + '.module', config.modFolder);
     
        	config.requires.push(config.desktopClass);
     
        	Ext.Array.each(modules, function(module) {
        		this.requires.push( this.name + '.module.' + module);
     
        	},config);
        	this.callParent(arguments);
        },
     
        getDesktopModuleClassName: function(name){
            return this.name + '.module.' + name;
        },
     
        launch : function() {
            Ext.create(this.desktopClass, this);
        }
    });
    sont fonctionnement est semblable à Application. pour tout les nom de modules présent dans le Système il définit un nom de classe et l'ajoute au requires.

    l'usage est le suivant
    Code javascript : 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
    Ext.onReady(function() {
    	new Ext.ux.desktop.System({
            name : 'MyDesktop',
     
            modules:[
               'SystemStatus',
               'VideoWindow',
               'Grid',
               'Tab',
               'Users',
               'Notepad',
               'BogusMenuModule',
               'BogusModule'
            ],
     
            desktopClass: 'Desktop'
     
        });
    });
    vous reconnaitrez les modules de l'exemple desktop.
    dans Application il faut définir une méthode launch qui desfini le viewport de l'appli et assure le démarrage.
    tel que je l'ai défini cette possibilité reste possible mais l'attribut desktopClass permet d'instancier un module qui assurera le démarage de l'application (du bureau dans mon exemple)

    ce premier module définit l'IHM de l'application et propose à l'utilisateur divers moyen de lancer un module. les modules ne font que définir des éléments d'IHM permettant leur lancement.
    ils référence comme une Application un ou des controlleurs et proposent une méthode run
    Code javascript : 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
    /*!
     * Ext JS Library 4.0
     * Copyright(c) 2006-2011 Sencha Inc.
     * licensing@sencha.com
     * http://www.sencha.com/license
     */
     
    Ext.define('MyDesktop.module.Users', {
        extend: 'Ext.ux.desktop.Application',
     
        controllers: ['Users'],
     
        id:'users-win',
        name: 'Users Manager',
        smallIcon: 'user-kid',
        largIcon:'accordion-shortcut',
     
        launcher: true,
        shortcut: true,
        quickStart: true,
     
     
        windowCfg: {
            id: 'user-win',
            width: 500,
            height: 300,
            animCollapse: false,
            constrainHeader: true,
            bodyBorder: true,
            border: false,
            layout: 'fit',
     
            items: [{
                xtype: 'userlist'
            }]
       }
    });
    il s'agit ici de l'intégration du tutoriel MVC UsersManager de Sencha, dans une fenêtre du bureau.
    la partit intérésante est dans la méthode run de Ext.ux.desktop.Application (classe crée pour la circonstance). elle contient un appel à loadControllers
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        loadControlers: function() {
        	if (!this.controllersOk) {
            	Ext.Array.each(this.controllers, function(controller) {
                    controllerName=this.app.system.getModuleClassName(controller, 'controller');
                    var controller = this.app.system.getController(controllerName);
                        controller.init(this.app);
            	}, this);
            	this.controllersOk = true;
        	}
     
        },
    la solution à mon problème se trouve dans ces trois lignes
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var controller = this.app.system.getController(controllerName);
        controller.init(this.app);
    }, this);
    je récupère une référence au système et je lui demande le controlleur Ext va alors charger les vues, stores et modèles associés. l'application pour le reste est exactement comme tout autre appli MVC.

    faire un cas particulier c'est bien en faire plusieurs ça permet de voir les difficultes.
    l'exemple Dsktop de sencha n'est pas toujours bien structuré. ainsi il définit un membre launcher dans dans le module qui est utilisé par le startMenu et qui appelle la création de la fenêtre en passant en parametre le launcher. pour les quickStart et shortcut les techniques sont différentes du coup impossible de faire comme le BogusMenuModule pour pur produire plusieurs shortcut le desktop ne sait pas les différencier. j'ai donc corrigé ce petit problème et j'ai entrepris de passer les modules défini par l'exemple en MVC. chose qui ses fait en quelques heures. (principalement pour corriger ces incohérences) J'ai tout de même voulu conserver la possibiliter de mixer des modules MVC avec d'autre qui ne le sont pas.

    cela faisait longtemps que je pensais à ce problème et j'avais envisagé diverses voies, sans jamais asser à l'acte. trops de chose à produire et trop éloigné de la solution MVC de Sencha.

    lorsque cette idée à germé hier je m'y suis mis et en 5 heures j'avais un bureau MVC fonctionnel contenant le tuto UserManager. 5 heures plus trad les modules de l'exemple sont passé en MVC et le fonctionnement du bureau à été rendu plus cohérent. le code de l'exemple Sencha très peut modifié : les modules on un launcher un shortcut et un quickStart qui fonctionne comme pour le launcher d'origine avec un handler fourni par le module (run) les code fignolé (pas assez commenté) et j'ai simulé un login et une gestion de session.

    pour ajouter un module au bureau:
    1. Developper une Appli MVC comme dans le tuto Sencha.
    2. Créer un module sur le modèle de Users
    3. Relancer le bureau


    A+JYT
    Ps: je vais documenter mon code et je vous le proposerais.

  2. #2
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    J'avais rencontré ce problème il y a un an avec une application que j'avais développé.

    Malheureusement je n'ai pas réussi à résoudre ce problème. A ce moment, la j'ai dut rétrograder de version de Extjs pour réussir à rendre le projet en temps et en heure.

    J'ai actuellement 2 projets en cours et 1 qui va commencer dans quelques semaines. Je serais donc ravis de pouvoir tester ta solution et si tu le souhaite de faire un retour d'expérience dessus.

  3. #3
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    pas de pb
    je suis en train de chercher à résoudre un autre problème

    comment utiliser les associations dans les modèles (voir la doc Data Package)
    dans un contexte MVC en utilisant des Data Store.

    pour le moment si je ne mets pas de datastore et que je mets des proxy dans les modèles j'arrive à faire fonctionner la chose sous MVC mais dès que je mets des stores ça ne fonctionne plus.

    A+JYT

  4. #4
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    Bonjour.

    j'ai ajouté quelque commentaires, retouché un peut le code

    le but de ce developpement est d'expérimenter le lancement diféré de module MVC avec ExtJS.

    je suis parti de l'exemple desktop avec comme première idée de ne pas le retoucher ou peut. en avançant j'ai changé d'avis et j'ai arrangé quelques petits éléments.

    fondamentalement l'exemple dscktop est très loint de de la structure MVC.
    je n'ai pas cherché à le remettre en cause. ce développement montre donc quelques limites. mais il m'a permis de trouvers une approche efficace pour intégrer des modules MVC dont le chargement est différé.

    je pris donc le lecteur de ne pas se concentrer sur le code en lui même mais sur les principes. pour un lancement MVC différé il faut une structure capable de l'acceuillir.
    la classe Ext.app.Application est là pour ça.
    il faut un lanceur. j'ai réutilisé le bureau de l'exemple sans trop le remettre en cause.
    typiquement je pense qu'un ensemble MCV standard démarant avec l'application peut très bien assurer ce rôle.
    Reste un le lancement proprement dit. pour lancer un module MVC faut-il le connaitre. c'est donc sur cette partit que porte l'idée de base.

    une classe dérivée de Ext.app.Application référence les modules de l'application et démarre les contrôleur de base (l'interface principale de l'application) le contrôleur lanceur de module réagit au demande de l'utilisateur et si besoin charge les contrôleurs MCV et ouvre la vue adéquate.

    les partie de code intérésantes se trouvent dans
    ux/js/System.js => dérivée de Ext.app.Application
    ux/js/App.js => ajoute getModules par rapport à la version sencha
    ux/js/Application.js => dérive de ux.Module.js et prends en charge le lancement du module MVC

    A+JYT
    Ps: j'ai denouveau un pb avec le bouton Gérer le spicèes jointes qui ne marche pas sur ma machine.
    Je vais changer de conf et poster le zip

  5. #5
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    ajout du zip
    Fichiers attachés Fichiers attachés

  6. #6
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    Bonjour.

    je suis repartis de mes idées, développées sur l'exemple Desktop

    et je l'ai appliqué au tutoriel MVC (légèrement amélioré)
    tout d'abord comme dans mes essais précédent j'ai dérivé Application
    Code javascript : 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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    Ext.define('Ext.ux.desktop.System', {
        extend: 'Ext.app.Application',
     
        constructor: function() {
            var config = Ext.applyIf(arguments[0] || {}, {
                name: 'MySys',
                modules: [],
                requires: [],
                appFolder: 'app',
                modFolder: 'modules',
                desktopClass: 'Desktop'
            });
     
            //accepte modules: "monModule"
            var modules = Ext.Array.from(config.modules);
     
            //défini le dossier où se trouves les modules
            config.modFolder = config.appFolder + '/' + config.modFolder;
     
            //ajoute le dossier module au class path
            Ext.Loader.setPath(config.name + '.module', config.modFolder);
     
            //ajoute toutes les classe de modules à l'application
            Ext.Array.each(modules, function(module) {
                this.requires.push( this.name + '.module.' + module);
     
            },config);
            //appel du constructeur parent
            this.callParent(arguments);
     
            //charger tous les modules au démarage
            this.on('launch', function() {
                this.getModules();
            });
        },
     
        //executer un module à la demande
        runModule: function(name) {
            this.loadControlers(this.modules[name]);
        },
     
        //charge tous les modules
        getModules : function(){
            var ms = {};
            var me = this;
            Ext.Array.each(this.modules, function(module) {
                ms[module] = Ext.create(this.getModuleClassName(module, 'module'), {app: me});
            }, this);
            this.modules = ms;
            return ms;
        },
     
        //charge tous les controleurs (et donc views, stores et models) d'un module
        loadControlers: function(module) {
            if (!module.controllersOk) {
                Ext.Array.each(module.controllers, function(controller) {
                    controllerName=this.getModuleClassName(controller, 'controller');
                    var controller = this.getController(controllerName);
                    controller.init();
                    controller.application = this;
                }, this);
                module.controllersOk = true;
            }
     
        }
     
    });
    Comme on peut le constater j'ai rapatrié toute la gestion des module dans cette classe.
    l'application:
    Code javascript : 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
    Ext.Loader.setPath('Ext.ux.desktop', 'ux/js');
    Ext.Loader.setPath('Ext.ux.grid', 'ux/grid');
    Ext.require('Ext.ux.desktop.System');
     
    var MySystem;
    Ext.onReady(function() {
        MySystem = new Ext.ux.desktop.System({
            name : 'Hermes',
            appFolder : 'app',
            title : "Hermes",
     
            // Controleurs de l'application. permets de découper l'appli en module
            // indépendants.
            controllers : ['Main', 'Notification', 'Entete'],
     
            modules:['Users'],
     
            // démarage de l'application (après le onReady)
            launch : function() {
                Ext.widget('main');
                document.title = this.title;
            }
     
        });
    });
    On retrouve ici les mêmes élément que dans le tutoriel. le fonctionnement est en tout point identique à ce que propose Ext MVC.
    la présent de modules:['Users'], est légèrement différente. les classes modules seront chargé au démarage elles contiennent une liste de contrôleur.

    contrairement à ce que propose le tutoriel sencha j'ai défini un controleur main et une vue main qui gère la vue principale. l'application se contente donc de créer la vue Ext.widget('main');
    la vue main qui utilise un layout border avec un tabpanel
    Code javascript : 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
    Ext.define('Hermes.view.Main' ,{
        extend: 'Ext.container.Viewport',
        alias : 'widget.main',
     
    	layout : {
    		type : 'border',
    		// gère l'espace avec le bord du navigateur
    		padding : 5
    	},
    	defaults : {
    		split : true
    	},
    	items : [{
    		region : 'north',
            tbar: [
                   { xtype: 'button', text: 'users', action: 'show' }
               ],
    		xtype : 'entete'
    	}, {
    		region : 'center',
    		xtype : 'tabpanel',
    		items : [/*{
    			xtype : 'userlistdetail'
    		}, {
    			title : 'details',
    			id : 'userdetail',
    			xtype : 'useredit'
    		}*/]
    	}]
     
    });
    controleur main gère le bouton "Users" qui lencera le module du même nom
    Code javascript : 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
    Ext.define('Hermes.controller.Main', {
        extend: 'Ext.app.Controller',
     
        views: ['Main'],
     
        init: function() {
            //on défini les actions associés au événements.
            this.control({
                'main button[action=show]': {
                    click: this.showUser
                }
            });
        },
     
        showUser: function(buton, event) {
            this.application.runModule('Users');
            buton.up('main').down('tabpanel').add({
                xtype : 'userlistdetail'
            });
            buton.up('main').down('tabpanel').add({
                title : 'details',
                id : 'userdetail',
                xtype : 'useredit'
            });
        }
    });
    lors d'un click sur le bouton on appelle this.application.runModule('Users'); qui va charger les controleurs du module users ainsi que les vue associées.

    le module users
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Ext.define('Hermes.module.Users', {
        controllers: ['Users']
    });

    je vous laisse découvrir le reste du code dans le ZIP
    A+JYT
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. Réponses: 4
    Dernier message: 17/04/2013, 20h25
  2. Réponses: 11
    Dernier message: 01/04/2008, 14h42
  3. [SITE] Conceptualiser un site multi modules.
    Par proner dans le forum Maven
    Réponses: 7
    Dernier message: 29/10/2007, 14h14
  4. [Reporting] Récursivité multi-modules
    Par elitost dans le forum Maven
    Réponses: 4
    Dernier message: 08/09/2006, 08h27
  5. BUILD ERROR sur création d'un projet multi-modules
    Par elitost dans le forum Maven
    Réponses: 1
    Dernier message: 28/08/2006, 15h23

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