• [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的指向。

  • 相关阅读:
    营销型站点的建设流程是什么?
    MAC 通过brew安装软件
    Android实现分享内容到微信朋友圈
    C++设计模式之适配器模式(三)
    JEECG平台权限设计
    .Net修改网站项目调试时的虚拟目录(未验证)
    .Net修改网站项目调试时的虚拟目录
    ECharts.js学习动态数据绑定
    百度ECharts
    asp.net loading 动画
  • 原文地址:https://www.cnblogs.com/No-harm/p/9674101.html
Copyright © 2020-2023  润新知