ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

什么是MVC?

2019-07-03 18:22:55  阅读:220  来源: 互联网

标签:name 什么 li content MVC let model view


å¾çMVC是一种设计模式,既是一种代码组织形式又是一种思想,他将系统分为三层:Model 数据,View 视图,Controller 控制器。

Model数据管理:专门处理数据,包括数据逻辑,数据请求,数据存储。它不对HTML,DOM,CSS以及视图逻辑进行操作,一般多数用于从服务器获取数据和保存数据。

View视图:即为用户可见区域,前端view主要负责HTML的渲染。

Controller控制器:主要负责view事件的逻辑处理,并更新Model,也监听View,总而言之Controller控制除视图和数据以外所有的事情。

下面我们通过一个原生JS例子来认识MVC这种设计模式。


这是一个留言板功能模块,我从leancloud注册了一个账号,作为数据库。然后在html中加入提交表单,绑定表单事件。输入信息提交后由js向leancloud服务器申请保存数据,保存成功后我们再从leancloud中拿到数据渲染到页面中,就这样简单的一个功能模块,我们试着用MVC的设计模式重构一遍。

重构前:

html

<script src="//cdn.jsdelivr.net/npm/leancloud-storage@3.14.0/dist/av-min.js"></script>
<section class="leave">
    <h2>留言板</h2>
    <ol id="messageList"></ol>
    <div class="inputBox">
        <form id="message">
            <div>
                昵称<input type="text" autocomplete="off" name="name">
            </div>
            <div>
                内容<input type="text" autocomplete="off" name="content">
            </div>
            <input type="submit" name="提交" style="margin-top: 20px">
        </form>
    </div>
</section>

JS

//leancloud初始化,
var APP_ID = '6cdlCTFh4O4BU9GaTp79Fc4R-gLGzoHsz';
var APP_KEY = 'PrnMib9dmf7qc9B4vEEvOfm6';

AV.init({
    appId: APP_ID,
    appKey: APP_KEY
});

//从leancloud拿到数据
let query = new AV.Query('A_Tione')
query.find().then(e=>{
    let array = e.map(item=> item.attributes)//拿到A_Tione的留言数据
    console.log(array)
    array.forEach((item)=>{
        let li = document.createElement('li')
        li.innerText = item.name+':'+item.content
        messageList.appendChild(li)
    })

})

//将表单数据保存到leancloud中
let myForm = document.querySelector('#message')
myForm.addEventListener('submit', function (e) {
    e.preventDefault() //阻止默认事件
    let name = myForm.querySelector('input[name=name]').value
    let content = myForm.querySelector('input[name=content]').value
    let Tione = AV.Object.extend('A_Tione');
    let tione = new Tione();
    tione.save({
        'name': name,
        'content': content
    }).then(function(object) {
        let li = document.createElement('li')
        li.innerText = name+':'+content
        messageList.appendChild(li)
        myForm.querySelector('input[name=name]').value = ''
        myForm.querySelector('input[name=content]').value = ''
        console.log('保存成功')
    })

})

 我们可以看到代码是一坨坨的,需要用注释来区分 第一段是初始化,第二段是拿数据,第三段是保存数据。

现在代码少加上注释看起来还挺好理解的,可是代码行数上去了,哪怕加注释恐怕理解起来也不太容易,而且加太多注释同样耽误时间。于是乎经过程序员们不断地摸索,最后发现了一个办法,就是用MVC的思想,将代码分类整理,按照功能分为数据管理,视图和逻辑控制。


重构后:

第一步:

我们将html中包裹整个留言模块的DOM对象存入view变量中,这一步就是MVC中的V,view 视图

第二步:

然后在model对象中定义leancloud初始化,获取数据和新增数据,注意model中只做数据相关的逻辑以及拿数据和保存数据,其它的逻辑统统交给controller完成。这步就是MVC中的M,model 数据管理

第三步:

我们在controller对象中先定义好view: null, model: null, messageList: null,然后由controller中的init初始化从controller外面拿view,model,messageList。将他们三个的值保存到controller内部作用域中,这样的好处就是所有要用到的东西我们都能在controller中找到,不必再从外面调取,而且需要传进来的值已经定义好放在那了,你只需要按部就班地将需要的值传给定义好的空属性即可。

然后调用接下来的方法函数,进行视图相关的逻辑操作。例如在获取数据时调用model里面的this.model.fetch()方法,得到一个promise对象然后接zhen()继续后面的逻辑操作。这样数据处理model与视图逻辑处理controller就解耦了,各自处理各自的事儿,不用像原来的代码全部混在一坨,需要看完所有的代码才能理解写的什么。最后这步就是MVC中的C,controller 控制器

理解了这个例子,你就会发现后面写代码都是一个套路,view相关的html,model数据处理,controller定义好需要用到的属性初始化,然后将视图相关的逻辑全部放在controller里面,最后controller.init(view, model)一下将view和model传入controller即可。

好处:

  • 按MVC思想将代码划分好后,就不用费力写注释,因为一眼就知道代码在干嘛。
  • 增强代码阅读性
  • 省事,按照MVC模板一套,改改controller的视图处理逻辑、model的数据请求与相应,一个模块就写完了。
!function () {
    let view = document.querySelector('section.leave')
    let model = {
        init: function () {
            let APP_ID = '6cdlCTFh4O4BU9GaTp79Fc4R-gLGzoHsz';
            let APP_KEY = 'PrnMib9dmf7qc9B4vEEvOfm6';
            AV.init({appId: APP_ID, appKey: APP_KEY});
        },
        fetch: function () {//获取数据
            let query = new AV.Query('A_Tione')
            return query.find() //返回一个Promise对象
        },
        save: function (name, content) {
            let Tione = AV.Object.extend('A_Tione');
            let tione = new Tione();
            if (name && content) {
                return tione.save({//返回一个Promise对象
                    'name': name,
                    'content': content
                })
            }
        }
    }

    let controller = {
        view: null,
        model: null,
        messageList: null,
        init: function (view, model) {
            this.view = view
            this.model = model
            this.messageList = view.querySelector('#messageList')
            this.form = view.querySelector('form')
            this.model.init()
            this.loadMessages()
            this.bindEvents()
        },
        loadMessages: function () {
            this.model.fetch().then(e => {
                let array = e.map(item => item.attributes)//拿到A_Tione的留言数据
                array.forEach((item) => {
                    let li = document.createElement('li')
                    li.innerText = item.name + ':' + item.content
                    this.messageList.appendChild(li)
                })
            })
        },
        bindEvents: function () {
            this.form.addEventListener('submit', (e) => {
                e.preventDefault() //阻止默认事件
                this.saveMessage()
            })
        },
        saveMessage: function () {
            let myForm = this.form
            let name = myForm.querySelector('input[name=name]').value
            let content = myForm.querySelector('input[name=content]').value
            this.model.save(name, content).then(object => {
                let li = document.createElement('li')
                li.innerText = name + ':' + content
                this.messageList.appendChild(li)
                myForm.querySelector('input[name=name]').value = ''
                myForm.querySelector('input[name=content]').value = ''
                console.log('保存成功')
            })
        },
    }
    controller.init(view, model)
}.call()

 

标签:name,什么,li,content,MVC,let,model,view
来源: https://blog.csdn.net/weixin_41819731/article/details/94482900

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有