MVC模式中的“Hello World”

时间:2011-12-13 23:42:57

标签: javascript model-view-controller design-patterns object-oriented-analysis

在某公司的采访中,我被问到这个问题。

你知道什么设计模式......然后我被告知要根据MVC设计模式编写最简单的“hello world”应用程序。

我想出了一个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.
后来我被告知警报是一种观点。关于MVC的基本概念,我知道模型中的任何更改都会报告给View。并且中间有一个控制器来调用方法。

您能否纠正我的方法,或者为hello world MVC应用程序提出替代解决方案。还解释了MVC的微妙方面。

感谢。

6 个答案:

答案 0 :(得分:100)

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;

Controller(C)侦听某种交互/事件流。在这种情况下,它是页面的加载事件。

模型(M)是数据源的抽象。

视图(V)知道如何从模型中呈现数据。

Controller告诉View使用Model中的某些内容。

在这个例子中

  • 除了实现某些界面
  • 之外,View对模型一无所知
  • 模型对视图和控制器一无所知
  • Controller了解Model和View,并告诉View对模型中的数据做些什么。

请注意,上述示例是用于演示目的的严格简化。对于JS MVC世界中真正的“hello world”示例,请查看todoMVC

答案 1 :(得分:19)

更好的例子

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 */

答案 2 :(得分:5)

MVC架构

我写了一篇关于MVC架构的文章。这里只有一些代码,希望有人觉得它有用。

//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();
    })();

从上面的例子可以看出,在这个设计中有三个不同的单元,每个单元都有一个特定的工作要执行。让我们从上面的基础结构构建MVC设计。可以有多个视图和Observer,这里只创建另一个视图。

// 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();
})(); 

这里理解的是模态不能依赖于视图或查看器或对数据执行的操作。数据模式可以独立,但视图和控制器是必需的,因为需要显示数据而另一个需要操作它。因此,视图和控制器是由模态而不是相反的方式创建的。

//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();

从上面可以看出,在视图和控制器之间建立了链接。这是MVC模式的要求之一。为了证明模态的变化,让我们改变程序并观察模态状态的变化是独立完成的,并在视图中反映出来。

//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();

当模态的状态改变时,控制器已将消息发送到视图以更新自身。这很好,但仍然有一个主要概念需要实现,即观察者或控制器需要由模态识别。为了看到这种情况,模态和控制器之间必须有一个链接,这样任何数量的控制器都可以显示对模态的兴趣,这被认为是将观察者注册到模态。这种关系是使用观察者不存在于空中的概念来实现的。它的存在是因为对模态产生了兴趣,因此当它被创建时,它必须使用它需要显示兴趣的模态创建,或者换言之,它可以访问模态。让我们看一下下面的例子,看看如何使用JavaScript简单而优雅地实现这个MVC设计模式。

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);

从上面可以看出观察者已经使用模态addObsever函数注册自己并建立了一个指向模态的链接。一旦创建了所有实例。手动更改模态状态以在视图中显示效果。通常在GUI环境中,通常通过用户按下任何按钮或从任何其他外部输入来完成更改。我们可以模拟随机发生器的外部输入并观察效果。在下面的示例中,数据中添加了更多元素以清楚地显示效果。

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();
}

上面的例子演示了MVC框架的使用,其中模态保持独立于视图和控制器。表示数据的模态负责通知所有已表示兴趣的相关方并使用模态注册自己。一旦发生任何变更,通知就会发送给各方,并留给他们采取行动。以下示例与上述示例略有不同,其中观察者仅显示新添加的数据。

    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");

人们可能想要添加的最后一件事是在不需要时删除观察者。这可以通过在模态调用中添加一个名为removeObserver(object)的方法来完成。上面的MVC设计模式可以通过使用子计算和顶级类中的共同功能来进一步细化,使设计尽可能简单,但留在其他一些文章中。希望它有所帮助。

答案 3 :(得分:1)

MVC是一种应该用于构建应用程序的设计模式。 MVC代表模型,视图,控制。基本上你应该将业务逻辑(模型)与用户界面(View)和控制逻辑分开。

例如:

您有一个用户类,可以从数据库加载用户,可以保存em。这是你的模特。

您有一个使用User类来记录用户的控制器。

控制器完成后,它会显示一个包含文本“Welcome $ username”的模板。

此外,模型不应该知道View和Controller,View不应该知道Controller,而Controller知道Model和View。

维基百科MVC:http://de.wikipedia.org/wiki/Model_View_Controller

答案 4 :(得分:0)

我认为你在这里忽略了这一点。

MVC是您用于设计应用程序的模式。我认为至少你希望能够改变模型,并看到视图中反映的变化。

您通常有一个对象来表示模型,一个不同的对象来表示“视图”(它可能介于模型和您用作视图的HTML对象之间)和一个控制器,将从您的HTML对象获取输入并更新模型。

因此,您更改编辑字段,编辑字段告诉控制器,控制器更新模型,模型将触发控制器用于更新依赖于此数据的任何其他视图组件的事件。

实施“hello world”版本还需要更多一行,但我认为这就是我要从这样的面试问题中寻找的。

答案 5 :(得分:0)

所以我做了一个简单的例子MVC,数据输出在console.log()

let model = {
    data: {
        text: "Hello World",
    },
};

let view = {
    init: function () {
        this.render();
    },

    render: function () {
        console.log(model.data.text);
    },
};

let controller = {
    init: function () {
        view.init();
    },
};

controller.init();