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

Mon programme Discussion :

[Javascript][MVC][AJAX] Un coup de main ?


Sujet :

Mon programme

  1. #1
    Membre confirmé Avatar de alejandro
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2004
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2004
    Messages : 167
    Par défaut [Javascript][MVC][AJAX] Un coup de main ?
    Bonjour à tous,

    Je suis en train de regarder pour implémenter AJAX et un modèle MVC Actif en Javascript. J'ai vu que par exemple Prototype apparemment le faisait (tout du moins pour Ajax) mais à 100Ko le script j'ai préféré m'y essayer ... je voulais des feedback sur ce bout de code qui ne marche pas encore mais qui ne doit pas en être loin :

    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    <html>
    <head>
        <script language="Javascript" type="text/javascript">
    
        // This is an active MVC Model
        function Model() // Observable + State
        {
            // List the current observers
            this.observers = new Array();
            
            // Add an observer to the observers stack
            function Attach( Observer )
            {
                this.observers.push( Observer );
            }
            this.Attach = Attach;
            
            // Remove an observer from the observers stack
            function Detach( Observer )
            {
                for( var i in this.observers )
                {
                    if( this.observers[i] == Observer )
                    {
                        this.observers.splice( i , 1 );
                    }
                }
            }
            this.Detach = Detach;
            
            // Notify the observers to update
            function Notify()
            {
                for( var i in this.observers )
                {
                    this.observers[i].Update( this );
                }
            }
            this.Notify = Notify;
            
            // Current state
            this.state = 0;
            
            // Change the current model state
            function SetState( value )
            {
                this.state = value;
                this.Notify();
            }
            this.SetState = SetState;
        }
    
        // This is an active MVC View
    
        function View( Observable)
        {
            // Attach this view to Observable
            Observable.Attach( this );
    
            // Update this view
            function Update( Observable )
            {
                switch( Observable.state.GetState )
                {
                    case 1:
                        break;
                    case 2: 
                        break;
                    case 3:
                        break;
                    case 4:
                        Observable.state.Paint;
                        break;
                    default: // 0
                        break;
                }
            }
            this.Update = Update;
            
        }
    
        // This is an active MVC Controller
        function Controller( Observable )
        {
            // Attach this view to Observable
            Observable.Attach( this );
    
            // Update this view
            function Update( Observable )
            {
                switch( Observable.state.GetState )
                {
                    case 1:
                        alert('state 1');
                        break;
                    case 2: 
                        alert('state 2');
                        break;
                    case 3:
                        alert('state 3');
                        break;
                    case 4:
                        alert('state 4');
                        break;
                    default: // 0
                        Observable.state.Open;
                        break;
                }
            
            }
            this.Update = Update;
        }
    
        // Here is the classic active MVC architecture
    
        M = new Model();
        V = new View(M);
        C = new Controller(M);
    
        // With this one we create requests
    
        function Ajax( page , id )
        {
            // Current Context
            try
            { 
                this.XHR = new ActiveXObject( "Microsoft.XMLHTTP" );
            }
            catch( e )
            {
                this.XHR = new XMLHttpRequest();
            }
            
            // Update the model state
            this.XHR.onreadyStateChange = function() {
                M.SetState(this);
            }
            
            // Return the current state
            function GetState()
            {
                return this.XHR.readyState;
            }
            this.GetState = GetState;
            
            // Fill the current zone id
            function Paint()
            {
                document.getElementById(id).innerHTML = this.XHR.responseText;
            }
            
            // Open a connexion
            function Open()
            {
                this.XHR.open( 'GET' , page );
            }
            this.Open = Open;
            
            // Start the request
            M.SetState(this);
        }
    
        </script>
    </head>
    <body>
    
    <button id="bouton" onclick="Javascript: new Ajax( 'content.php' ,'divarea' );">Cliquez</button>
    <div id="divarea"></div>
    
    </body>
    </html>
    Maintenant place aux explications :

    On crée trois classes, le modèle, le contrôleur et la vue. Le modèle est un observable, c'est à dire qu'un objet qui désire l'observer peut s'inscrire via la méthode Attach() de notre modèle et se retrouver notifié des changements d'état de ce dernier.

    Justement en parlant de notifications, on attache le contrôleur et la vue à notre modèle de façon à ce qu'ils soient notifiés des changements d'état de notre modèle. Apparemment d'après les documentations que j'ai consulté c'est un modèle MVC Actif dans le sens où c'est notre modèle qui modifie le comportement de l'application tout seul en fonction des différents états qui lui sont transmis via son interface SetState.

    Ensuite on a une classe Ajax qui permet de :
    • Créer une nouvelle requête ajax sur un conteneur donné
    • Changer dynamiquement l'état de l'objet modèle via la méthode onreadyStateChange
    • Obtenir l'état de la requête via la méthode GetState()
    • Changer le contenu de notre conteneur en fonction des différents états de notre requête via la méthode paint()
    • Ouvrir dynamiquement la requête via la méthode open()
    • Démarrer le processus en modifiant l'état de notre modèle via la méthode SetState de ce dernier


    Le tout semble bien fonctionner au début puisqu'en plaçant des alert à différents endroits j'arrive à suivre le déroulement du script mais cela semble bloquer lorsque mon readyState change, soit donc apparemment dans cette partie de ma classe Ajax :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            // Update the model state
            this.XHR.onreadyStateChange = function() {
                M.SetState(this);
            }
    Donc si vous voyez ce qui peut clocher car je ne suis pas un expert en javascript. Ha oui j'oubliais, mais vous avez dû remarquer, pour mettre à jour un contenu c'est facile, on crée une nouvelle instance d'Ajax comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new Ajax( maPage , monConteneur );
    Ce qui moi m'intéresses pour développer entre autre des backoffice ou des parties de sites qui ne nécessitent pas entre autre de référencement.

    Bref votre avis m'intéresse ... de mon côté je continuerais de poster pour vous tenir au courant de l'avancée de ce petit projet que je trouve très sympa à coder. Le but final étant d'avoir un code le plus dépouillé possible et une interface utilisateur extrêmement simple d'utilisation.

  2. #2
    Membre confirmé Avatar de alejandro
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2004
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2004
    Messages : 167
    Par défaut
    Voilà mon petit programme qui est à présent fonctionnel. Il ne pèse que 3,22 Ko et permet d'assurer la gestion d'une interface graphique via un modèle MVC actif et AJAX. Idéal pour les applications web type backoffice ou zones privées.

    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    // This is an active MVC Model
    function Model() // Observable + State
    {
        // List the current observers
        this.observers = new Array();
        
        // Add an observer to the observers stack
        function Attach( Observer )
        {
            this.observers.push( Observer );
        }
        this.Attach = Attach;
        
        // Remove an observer from the observers stack
        function Detach( Observer )
        {
            for( var i in this.observers )
            {
                if( this.observers[i] == Observer )
                {
                    this.observers.splice( i , 1 );
                }
            }
        }
        this.Detach = Detach;
        
        // Notify the observers to update
        function Notify()
        {
            for( var i in this.observers )
            {
                this.observers[i].Update( this );
            }
        }
        this.Notify = Notify;
        
        // Current state
        this.state = 0;
        
        // Change the current model state
        function SetState( value )
        {
            this.state = value;
            this.Notify();
        }
        this.SetState = SetState;
    }
    
    // This is an active MVC View
    
    function View( Observable)
    {
        // Attach this view to Observable
        Observable.Attach( this );
    
        // Update this view
        function Update( Observable )
        {
            ID = Observable.state.id;
            switch( Observable.state.XHR.readyState )
            {
                case 1:
                    this.Paint( ID , 'OPENED STATE');
                    break;
                case 2:
                    this.Paint( ID , 'HEADERS RECEIVED');
                    break;
                case 3:
                    this.Paint( ID , 'LOADING');
                    break;
                case 4:
                    this.Paint( ID , Observable.state.XHR.responseText );
                    break;
                default: // 0
                    this.Paint( ID , 'UNSENT STATE');
                    break;
            }
        }
        this.Update = Update;
        
        function Paint( ID , String )
        {
            document.getElementById(ID).innerHTML = String;
        }
        this.Paint = Paint;
        
    }
    
    // This is an active MVC Controller
    function Controller( Observable )
    {
        // Attach this view to Observable
        Observable.Attach( this );
    
        // Update this view
        function Update( Observable )
        {
            switch( Observable.state.XHR.readyState )
            {
                case 1:
                    break;
                case 2: 
                    break;
                case 3:
                    break;
                case 4:
                    break;
                default: // 0
                    break;
            }
        
        }
        this.Update = Update;
    }
    
    // Here is the classic active MVC architecture
    
    M = new Model();
    V = new View(M);
    C = new Controller(M);
    
    // With this one we create requests
    
    function Request( page , id )
    {
        var self = this;
        self.id = id;
        
        // Current Context
        try
        { 
            self.XHR = new ActiveXObject( "Microsoft.XMLHTTP" );
        }
        catch( e )
        {
            self.XHR = new XMLHttpRequest();
        }
    
        // Start the request
        M.SetState(self);
    
        self.XHR.onreadystatechange = function() {
            M.SetState(self);
        }
        self.XHR.open( 'GET' , page + '?' + new Date().getTime() , false );
        self.XHR.send( null );
    }
    Voilà donc j'aimerais que ceux qui sont intéressés le testent pour me donner des feedbacks, améliorer etc. Pour l'utiliser vous attribuez une ID à un tag quelconque de votre page web et vous appelez votre fichier comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Request( "maPage.php" , "monID" );
    Ensuite voilà les explications sur le 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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    function Model()
    {
        this.observers = new Array();
        
        function Attach( Observer )
        {
            this.observers.push( Observer );
        }
        this.Attach = Attach;
        
        function Detach( Observer )
        {
            for( var i in this.observers )
            {
                if( this.observers[i] == Observer )
                {
                    this.observers.splice( i , 1 );
                }
            }
        }
        this.Detach = Detach;
        
        function Notify()
        {
            for( var i in this.observers )
            {
                this.observers[i].Update( this );
            }
        }
        this.Notify = Notify;
        
        this.state = 0;
        
        function SetState( value )
        {
            this.state = value;
            this.Notify();
        }
        this.SetState = SetState;
    }
    La classe Model permet d'instancier un modèle de données. Notre application MVC étant active, c'est le changement d'état de ce modèle qui provoque la mise à jour des objets qui y sont rattachés via la méthode Attach(). La méthode Detach() permettant quand à elle de détacher un objet de la liste des observateurs du modèle (la propriété observers). Enfin la propriété state contient l'état courant de notre modèle et elle est mise à jour via la méthode SetState qui ensuite appelle Notify qui se charge de mettre à jour les objets observateurs ayant tous pour point commun la méthode Update().

    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
    function View( Observable)
    {
        Observable.Attach( this );
    
        function Update( Observable )
        {
            ID = Observable.state.id;
            switch( Observable.state.XHR.readyState )
            {
                case 1:
                    this.Paint( ID , 'OPENED STATE');
                    break;
                case 2:
                    this.Paint( ID , 'HEADERS RECEIVED');
                    break;
                case 3:
                    this.Paint( ID , 'LOADING');
                    break;
                case 4:
                    this.Paint( ID , Observable.state.XHR.responseText );
                    break;
                default: // 0
                    this.Paint( ID , 'UNSENT STATE');
                    break;
            }
        }
        this.Update = Update;
        
        function Paint( ID , String )
        {
            document.getElementById(ID).innerHTML = String;
        }
        this.Paint = Paint;
        
    }
    La classe View est développée par rapport à la fonction Request() et est articulée autour de l'objet XHR (pour XMLHttpRequest) qu'elle instancie. En fonction de l'état du Modèle, elle peut afficher des informations différentes à l'intérieur du conteneur spécifié lors de l'appel à la fonction Request() en fonction des besoins de l'application. Notez la présence de la méthode Paint qui permet simplement de modifier le contenu HTML de l'élément ciblé par son ID unique.

    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
    function Controller( Observable )
    {
        Observable.Attach( this );
    
        function Update( Observable )
        {
            switch( Observable.state.XHR.readyState )
            {
                case 1:
                    break;
                case 2: 
                    break;
                case 3:
                    break;
                case 4:
                    break;
                default: // 0
                    break;
            }
        
        }
        this.Update = Update;
    }
    La classe Controller est pour l'instant inutilisée. Normalement vous pouvez l'utiliser pour le traitement des actions utilisateur (si vous souhaitez que votre application change de comportement en fonction des actions utilisateur. On peut très bien imaginer que vous attachiez un autre objet qu'une Request() et que votre contrôleur réagisse à cet objet plutôt qu'à une requête AJAX. On peut également envisager que ce dernier réagisse en fonction de l'état de traitement de la requête AJAX, ce qui est entre autre le cas ici puisqu'il réagit en fonction de la propriété readyState de l'objet XHR créé par la fonction Request();

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    M = new Model();
    V = new View(M);
    C = new Controller(M);
    Ci-dessus une démonstration de comment vous créez et attachez des objets au modèle. Dans le cas présent, on crée un objet Modèle via "new Model()". Puis on y rattache une Vue et un Controleur en passant le modèle en argument. Chaque instance de View() ou de Controller() fait un appel à la méthode Attach() du modèle en passant "this" en paramètres ce qui fait que l'objet s'enregistre automatiquement auprès du modèle.

    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
    function Request( page , id )
    {
        var self = this;
        self.id = id;
        
        try
        { 
            self.XHR = new ActiveXObject( "Microsoft.XMLHTTP" );
        }
        catch( e )
        {
            self.XHR = new XMLHttpRequest();
        }
    
        // Start the request
        M.SetState(self);
    
        self.XHR.onreadystatechange = function() {
            M.SetState(self);
        }
        self.XHR.open( 'GET' , page + '?' + new Date().getTime() , false );
        self.XHR.send( null );
    }
    Pour terminer la fonction Request permet d'instancier une requête AJAX sur un objet identifié par une ID unique. A chaque changement d'état de notre objet AJAX, le modèle est mis à jour et le contrôleur et la vue sont automatiquement notifiés de ce changement d'état et peuvent réagir en fonction de ce dernier. Il suffit de les modifier pour leur faire adopter le comportement souhaité.

    Finalement comme je vous l'ai indiqué au début du post si vous avez des feedbacks, des retours de bugs ou quoi que ce soit ... répondez-moi via ce post pour améliorer ce petit script sur lequel je suis en train de travailler.

Discussions similaires

  1. Besoin d'un coup de main sur PHP/javascript pour passage variables
    Par oliopur78 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 02/03/2012, 19h54
  2. Réponses: 3
    Dernier message: 28/02/2003, 17h06

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