1. 程式人生 > >[JavaScript]MVC淺析

[JavaScript]MVC淺析

listen scrip view nds save 數據庫 以及 obj 做出

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視圖。

用一張圖來表示就是:

技術分享圖片

接下來改寫一下之前使用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的指向。

[JavaScript]MVC淺析