65.9K
CodeProject 正在变化。 阅读更多。
Home

JavaScript 中的 MVC 入门

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.89/5 (8投票s)

2014年12月2日

CPOL

5分钟阅读

viewsIcon

31507

downloadIcon

93

一个非常小的单页应用,使用普通的 JavaScript、jQuery、HTML(无框架)

JavaScript 中的 MVC

为了理解 JavaScript 中的 MVC,我将首先简要解释 MVC——MVC 中每个组件的目的是什么,这种模式是如何流行的,以及你如何使用 JavaScript 来实现它?在本文的最后,我将分享一个我用 JavaScript 中的 MVC 创建的示例(任务检查器)。

1. 模型 (Model)

它仅仅意味着数据。任何用于存储数据的 datamember 或任何 datastructure 都将被称为模型。此外,用于 insert/delete 数据的方法或其他用于在数据上执行不同操作的方法也只会在模型中编写。例如,一个 employee 对象可以包含员工姓名、ID、薪资、工作经验等。在这里,employee 对象是一个模型,因为它代表实际数据。

2. 视图

这是 MVC 中我们屏幕上看到的部分。顾名思义,视图 (View) 包含将用于显示数据 (data) 的用户界面。这些数据将从模型中获取。这意味着,每个视图对象都包含一个模型对象。例如,UI 上显示 employee 数据的表格,这里这个表格就是使用视图对象创建的。

3. 控制器 (Controller)

这是 MVC 中同时利用视图和模型的部分。

一个通用的事件绑定写在控制器里面。当应用程序启动时,控制器会初始化应用程序,在那里绑定通用事件。例如,点击一个按钮时,应该创建一个 employee 对象。这个事件绑定可以写在控制器里面。
注意:在某些情况下,您可以在控制器中编写此类代码,也可以创建一个单独的视图并将相同的代码写在该视图中。因此,MVC 中的 'C' 始终是一个讨论的焦点。

4. 集合 (Collection)

有时,您希望将多个模型存储在一个单独的实体中。在这种情况下,集合非常有用。我将在下面的示例中说明如何创建集合。

为什么选择 MVC?

通过使用 MVC 方法构建应用程序,您可以获得许多优势,但我个人认为可伸缩性和可重用性是最好的好处。当您的应用程序变得越来越大时,您不能只是随便修改每一个文件。相反,您需要在同一个文件中添加新的更改,而 MVC 结构将确保您的代码能够正常运行。

如果您正在创建一个 employee 目录,那么您需要显示每个 employee 的详细信息,这些信息肯定会因各个 employee 而异。在这种情况下,通过使用 MVC,您可以为 employee 对象(称为 Model)提供一个通用的结构,并为每个 employee 的视图提供一个通用的结构。之后,您可以创建任意数量的 employee(每个都有不同的详细信息),并且每个 employee 的详细信息都可以通过视图在 UI 上显示。
此外,如果其他应用程序需要相同的 employee 对象,请随时在那里重用它。:)

解释 JavaScript 中 MVC 的示例应用程序

应用名称:任务检查器 (Task Checker)

主要功能

  1. 添加不同的任务
  2. 删除已完成的任务

HTML 结构

HTML 结构非常简单,有两个非常重要的标签。第一个 ID 为 'template',另一个 ID 为 'task-box'。template div 是一个生成视图,将用于显示所有任务。容器 div 是 'task-box' div。在这个 div 内部,将追加所有视图。

JS 结构

在 JS 文件中,我们创建了一个模型类、一个集合类、一个视图类和一个控制器类。我们在多个地方使用了 'this',但我现在无法详细说明,所以请尽量忽略它。我相信您无需非常理解 'this' 也能轻松理解这个示例。

var collection = new taskCollection();

var view = new taskView();
var controller = new taskController(collection,view);
controller.init();
  1. 由于模型意味着数据,我们的 taskModel 将有两个变量(数据存储在变量中)。变量 'task' 代表任务名称,'removeFlag' 用于识别是否应该删除特定任务。

    function taskModel(){
    
    var task="";
    var removeFlag=false;
    
        this.setTask = function(taskName){
        task = taskName;
        }
    
        this.getTask = function(){
        return task;
        }
    
        this.setFlag = function(flag){
        removeFlag = flag;
        }
    
        this.getFlag = function(){
        return removeFlag;
        }
    }

    在此模型中,除了拥有 'task' 和 'removeFlag' 两个属性外,我们还创建了它们的 getter 和 setter。

  2. 还有一个名为 taskCollection集合。此函数提供任务集合。除了 getter/setter,还有两个名为 addTaskkeepTask 的方法。addTask 方法向集合添加更多任务。keepTask 设置标志的值,该标志用于识别此任务应保留还是删除。

    function taskCollection(){
    
    var tasks = [];
    
        this.getTasks = function(){
        return tasks;
        }
    
        this.setTasks = function(tempTasks){
        tasks = tempTasks;
        }
    
        this.addTask = function(task){
        tasks.push(task);
        }
    
        this.keepTask = function(taskVal,flag){
        for(index in tasks){
                if(taskVal==tasks[index].getTask()){
                tasks[index].setFlag(flag);
                break;
                }
            }
        }
    }
  3. 之后,还有另一个类名为 taskView。这是我们应用程序的视图。这里创建了两个方法:showAllTasksshowTask。这里,showAllTasks 方法非常重要。此方法从上一步创建的任务集合中获取所有任务。收到所有任务后,它会显示所有 flag 设置为 false 的任务,并最终用所有仍然活动的任务更新任务集合(请记住,Task 集合是模型的集合,每个模型都有一个 'flag' 属性)。

    还有一个名为 showTask 的方法,此方法仅显示单个任务,即传递给此方法的任何模型。但在 showAlltasks 的情况下,所有任务都从集合中显示,并且 flag 属性设置为 false

    请注意,当删除任何任务并重新显示所有其他任务时会调用 showAllTasks,而当添加任何任务时会调用 showTask

    function taskView(){
    
        var template = $('.task','#template');
        this.showAllTasks=function(taskAllCollection){
    
        var tempCollectionTasks=[];
        var taskCollection = taskAllCollection.getTasks();
        var len = taskCollection.length;
    
        $('#task-box').html("");
    
        for(index=0;index<len;index++){
                var task = taskCollection[index];
                var template = $("#template");
                if(!task.getFlag()){
                template.find('.task').html(task.getTask());
                $('#task-box').append(template.html());
                tempCollectionTasks.push(task);
                }
        }
            taskAllCollection.setTasks(tempCollectionTasks);
        }
    
        this.showTask = function(taskModel){
                var template = $("#template");
                template.find('.task').html(taskModel.getTask());
                $('#task-box').append(template.html());
        }
    }
  4. 之后,还有一个类,那就是我们的控制器。控制器使用视图和集合对象。这里创建了 init 方法,该方法在 add 按钮上绑定事件。此方法创建一个模型对象,在该模型上设置任务,将此模型添加到集合中,并使用其视图显示此模型的详细信息。

    我认为,一旦您看到代码,其余部分就会不言而喻。

    function taskController(collection,view){
    
        this.init= function(){
            $('#add-btn').off('click').on('click',function(){
            var taskVal = $('#task-name').val();
            if(taskVal.trim()!=''){
                $('#task-name').val('');
                var model = new taskModel();
                    model.setTask(taskVal);
                    collection.addTask(model);
                    view.showTask(model);
            }
            else{
                alert('Please enter some value!!');
                return;
            }
    
            });
            this.addEvent();
        }
    
        this.addEvent = function(){
          $('#task-box').off('click').on('click','.close',function(ev){
            if($(ev.currentTarget).is(':checked')) {
                $(ev.currentTarget).parent().css('text-decoration','line-through');
                var taskVal = $(ev.currentTarget).parent().find('.task').text();
                collection.keepTask(taskVal,true);
    
            }
            else{
                $(ev.currentTarget).parent().css('text-decoration','none');
                var taskVal = $(ev.currentTarget).parent().find('.task').text();
                collection.keepTask(taskVal,false)
            }
        });
    
        $('#remove-btn').off('click').on('click',function(){
            view.showAllTasks(collection);
        });
    
        }
    }
  5. 最后,您需要创建这些对象才能使应用程序正常运行。

历史

  • 2014 年 12 月 2 日:初始版本
© . All rights reserved.