Dans une interview pour une entreprise, on m'a posé cette question.
Quels modèles de conception connaissez-vous ... alors on m'a dit d'écrire l'application la plus simple "bonjour le monde" basée sur MVC Design Pattern.
Je suis venu avec un programme JavaScript
var arr = ["a","b","c","d"]; // this is an array, same as store or model
alert(arr[0]); // this is controller
//and browser alert is a view.
plus tard, on m'a dit que l'alerte est une vue. Le concept de base sur MVC, je sais, est que tout changement dans le modèle est signalé à View. Et il y a un contrôleur entre les deux pour appeler les méthodes.
Pouvez-vous corriger mon approche ou trouver une solution alternative pour l'application MVC Hello World? Expliquez également les aspects subtils de MVC.
Merci.
var M = {}, V = {}, C = {};
M.data = "hello world";
V.render = function (M) { alert(M.data); }
C.handleOnload = function () { V.render(M); }
window.onload = C.handleOnLoad;
Le contrôleur (C
) écoute une sorte de flux d'interaction/d'événement. Dans ce cas, c'est l'événement de chargement de la page.
Le modèle (M
) est l'abstraction d'une source de données.
View (V
) sait comment restituer les données du modèle.
Le contrôleur demande à View de faire quelque chose avec quelque chose du modèle.
Dans cet exemple
Notez que l'exemple ci-dessus est une simplification importante à des fins de démonstration. Pour des exemples réels "hello world" dans le monde JS MVC, jetez un œil à todoMVC
Un meilleur exemple
var M = {}, V = {}, C = {};
/* Model View Controller Pattern with Form Example */
/* Controller Handles the Events */
M = {
data: {
userName : "Dummy Guy",
userNumber : "000000000"
},
setData : function(d){
this.data.userName = d.userName;
this.data.userNumber = d.userNumber;
},
getData : function(){
return data;
}
}
V = {
userName : document.querySelector("#inputUserName"),
userNumber : document.querySelector("#inputUserNumber"),
update: function(M){
this.userName.value = M.data.userName;
this.userNumber.value = M.data.userNumber;
}
}
C = {
model: M,
view: V,
handler: function(){
this.view.update(this.model);
}
}
document.querySelector(".submitBtn").addEventListener("click", function(){
C.handler.call(C);
});
/* Model Handles the Data */
/* View Handles the Display */
J'ai écrit un article sur l'architecture MVC. Voici seulement du code présent, j'espère que quelqu'un le trouvera utile.
//Modal
var modal = { data: "This is data"};
//View
var view = { display : function () {
console.log ("////////////////////////////");
console.log ( modal.data);
console.log ("////////////////////////////");
}
};
//Controller
var controller = ( function () {
view.display();
})();
À partir de l'exemple ci-dessus, comprenez simplement qu'il y a trois unités différentes dans cette conception où chacune a un travail spécifique à effectuer. Construisons la conception MVC à partir de la structure ci-dessus. Il peut y avoir plus d'une vue et Observer, ici seule une autre vue est créée en premier.
// Modal
var modal = { data: "This is data"};
// View
var slashView = { display : function () {
console.log ("////////////////////////////");
console.log ( modal.data);
console.log ("////////////////////////////");
}
};
var starView = { display : function () {
console.log ("****************************");
console.log ( modal.data);
console.log ("****************************");
}
};
// Controller
var controller = ( function () {
slashView.display();
starView.display();
})();
Ce qui est compris ici, c'est que le modal ne doit dépendre ni de la vue, ni des téléspectateurs, ni des opérations effectuées sur les données. Le modal de données peut être autonome mais la vue et le contrôleur sont nécessaires car l'un doit montrer les données et l'autre doit les manipuler. Ainsi, la vue et le contrôleur sont créés à cause du modal et non l'inverse.
//Modal
var modal = {
data : ["JS in object based language"," JS implements prototypal inheritance"]
};
// View is created with modal
function View(m) {
this.modal = m;
this.display = function () {
console.log("***********************************");
console.log(this.modal.data[0]);
console.log("***********************************");
};
}
function Controller(v){
this.view = v;
this.informView = function(){
// update the modal
this.view.display();
};
}
// Test
var consoleView = new View(modal);
var controller = new Controller(consoleView);
controller.informView();
De ce qui précède, on peut voir qu'il y a un lien établi entre la vue et le contrôleur. Et c'est l'une des exigences du modèle MVC. Pour démontrer le changement dans le modal, changeons le programme et observons que le changement dans l'état du modal se fait indépendamment et se reflète dans la vue.
//Modal
function Modal(){
this.state = 0;
this.data = ["JS is object based language","JS implements prototypal inheritance"];
//
this.getState = function (){
return this.state;
};
this.changeState = function (value) {
this.state = value;
};
}
// View is created with modal
function View(m) {
this.modal = m;
this.display = function () {
console.log("***********************************");
console.log(this.modal.data[modal.getState()]);
console.log("***********************************");
};
}
//controller is created with the view
function Controller(v){
this.view = v;
this.updateView = function(){
// update the view
this.view.display();
};
}
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(consoleView);
controller.updateView();
// change the state of the modal
modal.changeState(1);
controller.updateView();
Lorsque l'état du modal est modifié, le contrôleur a envoyé le message à la vue pour se mettre à jour. C'est bien, mais il reste un concept principal à mettre en œuvre et c'est l'observateur ou le contrôleur qui doit être identifié par le modal. Pour que cela se produise, il doit y avoir un lien entre le modal et le contrôleur afin qu'un nombre quelconque de contrôleurs puissent montrer l'intérêt pour le modal, cela est considéré comme l'inscription de l'observateur au modal. Cette relation navire est mise en œuvre en utilisant le concept que l'observateur n'existe pas dans l'air. Son existence vient de son intérêt pour le modal, donc quand il est créé, il doit être créé en utilisant le modal dont il a besoin pour montrer de l'intérêt ou en d'autres termes, il a accès au modal. Regardons l'exemple ci-dessous et voyons comment ce modèle de conception MVC est réalisé simplement et avec élégance en utilisant JavaScript.
function Modal(){
var stateChanged = false;
var state = 0;
var listeners = [];
var data = ["JS is object based language","JS implements prototypal inheritance"];
// To access the data
this.getData = function(){
return data;
};
// To get the current state
this.getState = function (){
return state;
};
// For simplicity sake we have added this helper function here to show
// what happens when the state of the data is changed
this.changeState = function (value) {
state = value;
stateChanged = true;
notifyAllObservers();
};
// All interested parties get notified of change
function notifyAllObservers (){
var i;
for(i = 0; i < listeners.length; i++){
listeners[i].notify();
}
};
// All interested parties are stored in an array of list
this.addObserver = function (listener){
listeners.Push(listener);
};
}
// View class, View is created with modal
function View(m) {
this.modal = m;
this.display = function () {
console.log("***********************************");
var data = this.modal.getData();
console.log(data[modal.getState()]);
console.log("***********************************");
};
}
// Controller or Observer class has access to both modal and a view
function Controller(m,v){
this.view = v;
this.modal = m;
this.modal.addObserver(this);
// update view
this.updateView = function(){
this.view.display();
};
// Receives notification from the modal
this.notify = function(){
// state has changed
this.updateView();
};
}
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(modal,consoleView);
// change the state of the modal
modal.changeState(1);
modal.changeState(0);
modal.changeState(1);
modal.changeState(0);
De ce qui précède, on peut voir que l'observateur s'est enregistré en utilisant la fonction modale addObsever et établit un lien vers le modal. Une fois toutes les instances créées. L'état modal a été modifié manuellement pour afficher l'effet dans la vue. Généralement, dans un environnement GUI, la modification est généralement effectuée avec un utilisateur appuyant sur n'importe quel bouton ou à partir de toute autre entrée externe. Nous pouvons simuler l'entrée externe du générateur aléatoire et observer l'effet. Ici, dans l'exemple ci-dessous, d'autres éléments sont ajoutés dans les données pour montrer clairement l'effet.
function Modal(){
var stateChanged = false;
var state = 0;
var listeners = [];
var data = [
"JS is object based language","JS implements prototypal inheritance",
"JS has many functional language features", "JS is loosely typed language",
"JS still dominates the Web", "JS is getting matured ","JS shares code
through prototypal inheritance","JS has many useful libraries like JQuery",
"JS is now known as ECMAScript","JS is said to rule the future of Web for
many years"];
//
this.getData = function(){
return data;
};
//
this.getState = function (){
return state;
};
this.changeState = function (value) {
state = value;
stateChanged = true;
notifyAllObservers();
};
function notifyAllObservers (){
var i;
for(i = 0; i < listeners.length; i++){
listeners[i].notify();
}
}
this.addObserver = function (listner){
listeners.Push(listner);
};
}
// View is created with modal
function View(m) {
this.modal = m;
this.display = function () {
console.log("****************************************************");
var data = this.modal.getData();
console.log(data[modal.getState()]);
};
//Adding external simulation of user sending input
this.pressButton = function(){
var seed = 10;
var number = Math.round(Math.random() * seed) ;
// change the state of modal
this.modal.changeState(number);
};
}
// Controller class needs modal and view to communicate
function Controller(m,v){
this.view = v;
//console.log(this.view.display);
this.modal = m;
this.modal.addObserver(this);
this.updateView = function(){
// update the view
//console.log(this.view);
this.view.display();
};
this.notify = function(){
// state has changed
this.updateView();
};
}
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(modal,consoleView);
// change the state of the modal
for ( var i = 0 ; i < 10; i++){
consoleView.pressButton();
}
L'exemple ci-dessus montre l'utilisation de la trame MVC dans laquelle un modal est conservé indépendamment de la vue et du contrôleur. Le modal représentant les données est chargé de notifier toutes les parties intéressées qui ont manifesté leur intérêt et se sont inscrites auprès du modal. Dès qu'un changement survient, une notification est envoyée aux parties et une action leur est laissée. L'exemple ci-dessous est légèrement différent de celui ci-dessus où seules les données nouvellement ajoutées sont affichées par l'observateur.
function Modal(){
var stateChanged = false;
var listeners = [];
var data = ["JS is object based language"];
// To retrieve the data
this.getData = function(){
return data;
};
// To change the data by any action
this.modifyData = function (string) {
( data.length === 1 )? data.Push(string): data.unshift(string);
stateChanged = true;
notifyAllObservers();
};
// Notifies all observers
function notifyAllObservers (){
var i;
for(i = 0; i < listeners.length; i++){
listeners[i].notify();
}
}
// Requires to register all observers
this.addObserver = function (listener){
listeners.Push(listener);
};
}
// View is created with modal
function View(m) {
this.modal = m;
this.display = function () {
console.log("****************************************************");
var data = this.modal.getData();
console.log(data[0]);
console.log("****************************************************");
};
//Adding external simulation of user sending input
this.pressButton = function(string){
// change the state of modal
this.modal.modifyData(string);
};
}
// View class
function Controller(m,v){
this.view = v;
this.modal = m;
this.modal.addObserver(this);
// Updates the view
this.updateView = function(){
this.view.display();
};
// When notifies by the modal send the request of update
this.notify = function(){
// state has changed
this.updateView();
};
}
// Test
var modal = new Modal();
var consoleView = new View(modal);
var controller = new Controller(modal,consoleView);
consoleView.pressButton();
consoleView.pressButton("JS dominates the web world");
consoleView.pressButton("JQuery is a useful library of JS");
La dernière chose que l'on peut ajouter est de supprimer l'observateur lorsqu'il n'est pas nécessaire. Cela peut être fait en ajoutant une méthode appelée removeObserver(object)
dans les appels modaux. Le modèle de conception MVC ci-dessus peut être plus raffiné en utilisant le sous-calcul et en ayant une fonction commune présente dans la classe supérieure, ce qui rend la conception aussi simple que possible, mais elle est laissée sur un autre article. J'espère que ça aide.
MVC est un modèle de conception qui doit être utilisé pour structurer votre application. MVC signifie Model, View, Control. Cela signifie essentiellement que vous devez séparer votre logique métier (modèle) de votre interface utilisateur (vue) et de votre logique de contrôle.
Par exemple:
Vous avez une classe d'utilisateurs, qui charge les utilisateurs de la base de données, peut les enregistrer. Ceci est votre modèle.
Vous disposez d'un Controller qui utilise la classe User pour connecter un utilisateur.
Une fois le contrôleur terminé, il affiche un modèle contenant le texte "Welcome $ username".
En outre, le modèle ne doit pas connaître la vue et le contrôleur, la vue ne doit pas connaître le contrôleur, tandis que le contrôleur connaît le modèle et la vue.
Wikipédia sur MVC: http://de.wikipedia.org/wiki/Model_View_Controller
Je pense que vous manquez un peu le point ici.
MVC est un modèle que vous utiliseriez pour concevoir une application. Je pense au minimum que vous vous attendez à pouvoir changer de modèle et voir le changement reflété dans la vue.
Vous auriez généralement un objet pour représenter le modèle, un objet différent pour représenter la "vue" (qui servirait probablement de médiateur entre le modèle et les objets HTML que vous utilisez comme vue) et un contrôleur, qui prendrait des entrées à partir de vos objets HTML et mettez à jour le modèle.
Ainsi, vous modifiez un champ d'édition, le champ d'édition indique au contrôleur, le contrôleur met à jour le modèle, le modèle déclenche des événements que le contrôleur utilise pour mettre à jour tous les autres composants de vue qui dépendent de ces données.
Ce serait quelques lignes de plus pour implémenter une version "bonjour le monde", mais je pense que c'est ce que je rechercherais dans une question d'entrevue comme celle-ci.