zoukankan      html  css  js  c++  java
  • [JavaScript]MVC浅析

    MVC浅析

    MVC或多或少都有听说过,我知道如果要作为一个前端的话,MVC应该是一个显示技术水平的槛,是绕不过去的,所以我乖乖来写这篇文章,对MVC进行一些粗浅的分析和归纳,以加深对MVC的理解。

    MVC是一种代码组织形式,他把代码依据功能的不同划分成三个部分,分别是Model、Controller、View。

    View代表视图,Model代表对数据的操作(存储和获取等),Controller代表了View和Model两者之间的交互逻辑以及其他。

    他们之间的相互作用是这样的:用户对View视图做出了操作,监听着View视图的controller接收到了View的变化通知,然后按需求去调用Model,Model向server发出请求;server返回响应给Model,Model返回数据给Controller,Controller根据接收到的数据更新View视图。

    用一张图来表示就是:

    MVC

    接下来改写一下之前使用leanCloud添加数据库创建留言功能的代码:

    //message.js
    
    !function(){
        // 初始化
        var APP_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
        var APP_KEY = 'xxxxxxxxxxxxxxxxxxxxxx';
    
        AV.init({
        appId: APP_ID,
        appKey: APP_KEY
        });
    
        // 拉取历史留言
        var query = new AV.Query('Message');
        query.find().then(function (messages) {
            messages.forEach(function (item) {
                let li = $('<li></li>').text(item.attributes.name +':'+item.attributes.content)
                $('#comments').append(li)
            });
        }).then(function (messages) {
            // 更新成功
        }, function (error) {
            // 异常处理
        });
    
        let myForm = document.querySelector('#postMessage')
        // 为什么要监听表单的submit事件而不是button的click事件,因为一旦用户输完密码按回车键提交的话,监听就落空了.submit事件包括了点击和回车
        myForm.addEventListener('submit',function(e){
            // 阻止传播,防止点击刷新
            e.preventDefault()
    
            //获取输入框内的值
            let content = $('input[name="content"]').val()
            let name = $('input[name="name"]').val()
            var Message = AV.Object.extend('Message');
            var messages = new Message();
            messages.save({
                "name":name,
                "content":content ,
            }).then(function(object) {
                let li = $('<li></li>').text(object.attributes.name +':'+ object.attributes.content)
                $('#comments').append(li)
                myForm.querySelector('input[name="content"]').value = ''
            })
        })
    }.call()
    

    View

    View代表视图,因为我们只对这个提交表单和展示列表进行操作,所以View就是:

    var view = $('section.messages')
    

    Model

    Model代表对数据的操作(存储和获取等)。

    所以Model应该只负责保存提交上来的留言到leanCloud,和从leanCloud获取留言以及数据库初始化的工作(给服务器发送请求,接收服务器响应),返回数据给Controller:

    var model = {
        // 初始化
        init : function(){
            var APP_ID = 'xxxxxxxxxxxxxxxxx'
            var APP_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxx'
            AV.init({appId: APP_ID,appKey: APP_KEY})
        },
        //获取数据
        fetch:function(){
            var query = new AV.Query('Message');
            return query.find() //Promise对象
        },
    
        // 保存数据
        save:function(name,content){
            var Message = AV.Object.extend('Message')
            var messages = new Message();
            return messages.save({
                "name":name,
                "content":content ,
            })
        },
    }
    

    Controller

    Controller代表了View和Model两者之间的交互逻辑以及其他。

    所以,他会负责监听View的事件通知,对Model的调用;从Model获取返回数据,更新View视图。

    var controller = {
        view : null,
        model: null,
        init : function(view,model){
            this.model = model
            this.view = view
            this.myForm = document.querySelector('#postMessage')
            this.model.init()
            this.loadMessages()
            this.bindEvents()
        },
    
        //加载留言数据
        loadMessages : function () {
            this.model.fetch().then((messages) => {
                messages.forEach((item) => {
                    let span = $('<span></span>').text('发布于:'+ this.parseTime(item.createdAt))[0]
                    let li = $('<li></li>').text(item.attributes.name + ':' + item.attributes.content)
                    li.append(span)
                    $('#comments').append(li)
                });
            }).then(function (messages) {
                // 更新成功
            }, function (error) {
                // 异常处理
            });
        },
        bindEvents : function(){
            this.myForm.addEventListener('submit',(e) => {
                // 阻止传播,防止点击刷新
                e.preventDefault()
    
                this.saveMessages()
            })
        },
        saveMessages : function(){
            //保存数据
    
            //获取输入框内的值
            let content = $('input[name="content"]').val()
            let name = $('input[name="name"]').val()
            this.model.save(name,content).then((object) => {
                let span = $('<span></span>').text('发布于:'+ this.parseTime(object.createdAt))[0]
                let li = $('<li></li>').text(object.attributes.name +':'+ object.attributes.content)
                li.append(span)
                $('#comments').append(li)
                document.querySelector('#postMessage input[name="content').value = ''
            },function(error){
                console.log(error)
            })
        },
        parseTime:function(d){
            const newDate = d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() + ' '
                            + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds();
            return newDate;
        }
    }
    controller.init(view,model)
    

    整体MVC

    !function(){
        var view = $('section.messages')
    
        var model = {
            init : function(){
                var APP_ID = 'xxxxxxxxxxxxxxxxxxxxxxx'
                var APP_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
                AV.init({appId: APP_ID,appKey: APP_KEY})
            },
            //获取数据
            fetch:function(){
                var query = new AV.Query('Message');
                return query.find() //Promise对象
            },
    
            // 保存数据
            save:function(name,content){
                var Message = AV.Object.extend('Message')
                var messages = new Message();
                return messages.save({
                    "name":name,
                    "content":content ,
                })
            },
        }
    
        var controller = {
            view : null,
            model: null,
            init : function(view,model){
                this.model = model
                this.view = view
                this.myForm = document.querySelector('#postMessage')
                this.model.init()
                this.loadMessages()
                this.bindEvents()
            },
            loadMessages : function () {
                this.model.fetch().then((messages) => {
                    messages.forEach((item) => {
                        let span = $('<span></span>').text('发布于:'+ this.parseTime(item.createdAt))[0]
                        let li = $('<li></li>').text(item.attributes.name + ':' + item.attributes.content)
                        li.append(span)
                        $('#comments').append(li)
                    });
                }).then(function (messages) {
                    // 更新成功
                }, function (error) {
                    // 异常处理
                });
            },
            bindEvents : function(){
                this.myForm.addEventListener('submit',(e) => {
                    // 阻止传播,防止点击刷新
                    e.preventDefault()
    
                    this.saveMessages()
                })
            },
            saveMessages : function(){
                //获取输入框内的值
                let content = $('input[name="content"]').val()
                let name = $('input[name="name"]').val()
                this.model.save(name,content).then((object) => {
                    let span = $('<span></span>').text('发布于:'+ this.parseTime(object.createdAt))[0]
                    let li = $('<li></li>').text(object.attributes.name +':'+ object.attributes.content)
                    li.append(span)
                    $('#comments').append(li)
                    document.querySelector('#postMessage input[name="content').value = ''
                },function(error){
                    console.log(error)
                })
            },
            parseTime:function(d){
                const newDate = d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() + ' '
                                + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds();
                return newDate;
            }
        }
        controller.init(view,model)
    }.call()
    

    MVC只能使用Controller通过Model操作自身的View,功能划分合理,所以对其他的文件和View来说是解耦的。利于维护和编写。


    注意事项

    Controller中this的使用,箭头函数不会改变this的指向。

  • 相关阅读:
    Linux下sed,awk,grep,cut,find学习笔记
    Python文件处理(1)
    KMP详解
    Java引用详解
    解决安卓中页脚被输入法顶起的问题
    解决swfupload上传控件文件名中文乱码问题 三种方法 flash及最新版本11.8.800.168
    null id in entry (don't flush the Session after an exception occurs)
    HQL中的Like查询需要注意的地方
    spring mvc controller间跳转 重定向 传参
    node to traverse cannot be null!
  • 原文地址:https://www.cnblogs.com/No-harm/p/9674101.html
Copyright © 2011-2022 走看看