開發與維運

Java單體應用 – 項目實戰(後臺) – 03.後臺賬戶管理 – 07.JS代碼重構

原文地址:http://www.work100.net/training/monolithic-project-iot-cloud-admin-manager-js.html
更多教程:光束雲 - 免費課程

JS代碼重構

序號 文內章節 視頻
1 概述 -
2 Select2控件初始化通用模塊 -
3 消息提示通用模塊 -
4 表單驗證通用模塊 -
5 模態對話框通用模塊 -
6 各視圖文件代碼修改 -
7 實例源碼 -

請參照如上章節導航進行閱讀

1.概述

我們進行視圖頁面編碼時會編寫自己的JS腳本,同時也會使用第三方的UI控件,其實這些JS腳本及UI控件大多數都是通用的,都可以提煉為公用模塊,接下來我們將完成這些提煉工作。

2.Select2控件初始化通用模塊

頁面中用到 select 控件時,需要引入 Bootstrap 的樣式效果,要達到效果,則需在頁面加載時執行如下代碼:

//Initialize Select2 Elements
$('.select2').select2();

//Initialize Select2 Elements
$('.select2bs4').select2({
    theme: 'bootstrap4'
});

下面我們將如上代碼提取到一個公用的 js 文件中。

首先,在 /webapp/static/assets/js/ 目錄下新建一個文件 select2-utils.js,代碼如下:

let Select2 = function() {

    let handleInitSelect2 = function() {
        //Initialize Select2 Elements
        $('.select2').select2();

        //Initialize Select2 Elements
        $('.select2bs4').select2({
            theme: 'bootstrap4'
        });
    }

    return {
        init: function() {
            handleInitSelect2();
        }
    }
}();

$(function() {
    Select2.init();
});

然後,刪除原有頁面中的自定義 js 代碼,用引入文件的方式代替,代碼如下:

<script src="/static/assets/js/select2-utils.js"></script>

3.消息提示通用模塊

對於頁面中用到的消息提示,比如 操作成功操作失敗 ,我們是使用如下代碼實現的:

成功消息

const Toast = Swal.mixin({
    toast: true,
    position: 'top',
    showConfirmButton: false,
    timer: 2000,
    timerProgressBar: true,
    onOpen: (toast) => {
        toast.addEventListener('mouseenter', Swal.stopTimer)
        toast.addEventListener('mouseleave', Swal.resumeTimer)
    }
})

Toast.fire({
    type: 'success',
    title: '操作成功'
})

失敗消息

const Toast = Swal.mixin({
    toast: true,
    position: 'top',
    showConfirmButton: false,
    timer: 2000,
    timerProgressBar: true,
    onOpen: (toast) => {
        toast.addEventListener('mouseenter', Swal.stopTimer)
        toast.addEventListener('mouseleave', Swal.resumeTimer)
    }
})

Toast.fire({
    type: 'error',
    title: '操作錯誤'
})

提取公用

我們將如上方法提取到一個公用的 js 文件中,在 /webapp/static/assets/js/ 目錄下新建一個文件 message-utils.js,代碼如下:

let Message = function() {

    const toast = Swal.mixin({
        toast: true,
        position: 'top',
        showConfirmButton: false,
        timer: 2000,
        timerProgressBar: true
    })

    /**
     * 顯示成功信息
     */
    let handleShowSuccess = function(title) {
        toast.fire({
            type: 'success',
            title: title
        })
    }

    /**
     * 顯示失敗信息
     */
    let handleShowFail = function(title) {
        toast.fire({
            type: 'error',
            title: title
        })
    }

    return {
        showSuccess: function(title) {
            handleShowSuccess(title);
        },

        showFail: function(title) {
            handleShowFail(title);
        }
    }
}();

使用

首先,刪除原有頁面中的自定義 js 代碼,用引入文件的方式代替,代碼如下:

<script src="/static/assets/js/message-utils.js"></script>

然後,使用消息提示,如:

if (${baseResult.status != null && baseResult.status != 200}) {
    Message.showFail('${baseResult.message}');
}

4.表單驗證通用模塊

在對錶單進行驗證時,我們使用如下的 js 代碼:

$("#form").validate({
    rules: {
        userName: {
            required: true,
            minlength: 4,
            maxlength: 20
        },
        password: {
            required: true,
            minlength: 6,
            maxlength: 20
        },
        roles: {
            required: true,
            minlength: 1,
            maxlength: 3
        }
    },
    messages: {
        userName: {
            required: " 請輸入用戶名",
            minlength: " 用戶名不能小於4位",
            maxlength: " 用戶名不能大於於20位"
        },
        password: {
            required: " 請輸入密碼",
            minlength: " 密碼不能小於6位",
            maxlength: " 密碼不能大於於20位"
        },
        roles: {
            required: " 請選擇角色",
            minlength: " 至少選擇1個角色",
            maxlength: " 至多選擇3個角色"
        }
    },
    errorElement: 'span',
    errorPlacement: function(error, element) {
        error.addClass('invalid-feedback');
        element.closest('.form-group').children('label').append(error);
    },
    highlight: function(element, errorClass, validClass) {
        $(element).addClass('is-invalid');
    },
    unhighlight: function(element, errorClass, validClass) {
        $(element).removeClass('is-invalid');
    }
});

提取公用

接下來我們將表單驗證代碼提取到一個公用文件 form-validate-utils.js,代碼如下:

let FormValidate = function() {

    let form = $('#form');

    /**
     * 處理驗證
     */
    let handleValidate = function(formId, rules, messages) {
        if (formId != '' || formId != null) {
            form = $('#' + formId);
        }

        form.validate({
            rules: rules,
            messages: messages,
            errorElement: 'span',
            errorPlacement: function(error, element) {
                error.addClass('invalid-feedback');
                element.closest('.form-group').children('label').append(error);
            },
            highlight: function(element, errorClass, validClass) {
                $(element).addClass('is-invalid');
            },
            unhighlight: function(element, errorClass, validClass) {
                $(element).removeClass('is-invalid');
            }
        });
    }

    return {
        validate: function(formId, rules, messages) {
            handleValidate(formId, rules, messages);
        }
    }
}();

使用

首先,刪除原有頁面中的自定義 js 代碼,用引入文件的方式代替,代碼如下:

<script src="/static/assets/js/form-validate-utils.js"></script>

然後,使用表單驗證,如:

FormValidate.validate(
    'form',
    {
        userName: {
            required: true,
            minlength: 4,
            maxlength: 20
        },
        password: {
            required: true,
            minlength: 6,
            maxlength: 20
        },
        roles: {
            required: true,
            minlength: 1,
            maxlength: 3
        }
    },
    {
        userName: {
            required: " 請輸入用戶名",
            minlength: " 用戶名不能小於4位",
            maxlength: " 用戶名不能大於於20位"
        },
        password: {
            required: " 請輸入密碼",
            minlength: " 密碼不能小於6位",
            maxlength: " 密碼不能大於於20位"
        },
        roles: {
            required: " 請選擇角色",
            minlength: " 至少選擇1個角色",
            maxlength: " 至多選擇3個角色"
        }
    }
);

5.模態對話框通用模塊

提取公用

在執行刪除動作時,我們有個確認提示框,下面我們將其功能提取到公用的 modal-dialog-utils.js 文件中,代碼如下:

let ModalDialog = function() {

    /**
     * 彈出確認對話框
     * @param modalId
     * @param title
     * @param message
     * @param callback
     * @param callback_params
     */
    let handleShowConfirm = function(modalId, title, message, callback, callback_params) {
        let modal = $('<div id="' + modalId + '"></div>');

        let modalDialog = $('<div></div>');
        let modalContent = $('<div></div>');
        let modalHeader = $('<div></div>');
        let modalBody = $('<div></div>');
        let modalFooter = $('<div></div>');

        let html;

        // modal-header html
        modalHeader.attr('class', 'modal-header');
        html = '';
        html = html + '<h4 class="modal-title">' + title + '</h4>';
        html = html + '<button type="button" class="close" data-dismiss="modal" aria-label="Close">';
        html = html + '  <span aria-hidden="true">&times;</span>';
        html = html + '</button>';
        modalHeader.html(html)

        // modal-body html
        modalBody.attr('class', 'modal-body');
        html = '';
        html = html + '<p>' + message + '</p>';
        modalBody.html(html);

        // modal-footer html
        let btnCancel = $('<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>');
        let btnOk = $('<button type="button" class="btn btn-primary">確定</button>');
        btnOk.on('click', function() {
            modal.modal('hide');
            callback(callback_params);
        });

        modalFooter.attr('class', 'modal-footer');
        modalFooter.append(btnCancel);
        modalFooter.append(btnOk);

        // modal-content
        modalContent.attr('class', 'modal-content');
        modalContent.append(modalHeader);
        modalContent.append(modalBody);
        modalContent.append(modalFooter);

        // modal-dialog
        modalDialog.attr('class', 'modal-dialog');
        modalDialog.append(modalContent);

        modal.attr('class', 'modal fade');
        modal.append(modalDialog);
        modal.modal('show');

        $(modal).on('hidden.bs.modal', function(e) {
            modal.remove();
        })

        $("body").append(modal);
    }

    return {
        showConfirm: function(modalId, title, message, callback, callback_params) {
            handleShowConfirm(modalId, title, message, callback, callback_params);
        }
    }
}();

使用

首先,刪除頁面中的 modal 定義標籤,同時刪除原有頁面中的自定義 js 代碼,用引入文件的方式代替,代碼如下:

<script src="/static/assets/js/modal-dialog-utils.js"></script>

然後,重新定義刪除功能 JS 腳本代碼,如下:

// 單個刪除
function singleDelete(userKey) {
    ModalDialog.showConfirm('single-delete-confirm', '操作確認', '刪除後數據不可恢復,您確認要操作嗎?', singleDelete_callback, userKey);
}

function singleDelete_callback(userKey) {
    location.href = '/auth/manager/delete/' + userKey;
}

最後,刪除按鈕 onclick 事件增加如下代碼:

<button type="button" class="btn btn-danger btn-sm" onclick="singleDelete('${authManager.userKey}');"><i class="fas fa-trash"></i></button>

6.各視圖文件代碼修改

我們已經提取了如下幾個公用 js 文件:

  • /static/assets/js/select2-utils.js
  • /static/assets/js/message-utils.js
  • /static/assets/js/modal-dialog-utils.js

接下來需要將所有使用相關功能的視圖文件進行修改,我們以 managere_add.jsp 視圖文件為例,修改後的代碼如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
    <title>新增賬戶 - 後臺賬戶 | IoT-Admin</title>
    <jsp:include page="../includes/resources_head.jsp" />
</head>
<body class="hold-transition sidebar-mini">
<div class="wrapper">

    <jsp:include page="../includes/layout_header.jsp" />

    <jsp:include page="../includes/layout_left.jsp" />

    <!-- Content Wrapper. Contains page content -->
    <div class="content-wrapper">
        <!-- Content Header (Page header) -->
        <div class="content-header">
            <div class="container-fluid">
                <div class="row mb-2">
                    <div class="col-sm-6">
                        <h1 class="m-0 text-dark">新增賬戶</h1>
                    </div><!-- /.col -->
                    <div class="col-sm-6">
                        <ol class="breadcrumb float-sm-right">
                            <li class="breadcrumb-item"><a href="#">後臺賬戶</a></li>
                            <li class="breadcrumb-item active">新增賬戶</li>
                        </ol>
                    </div><!-- /.col -->
                </div><!-- /.row -->
            </div><!-- /.container-fluid -->
        </div>
        <!-- /.content-header -->

        <!-- Main content -->
        <div class="content">
            <div class="container-fluid">
                <div class="row">
                    <div class="col">
                        <div class="card card-gray">
                            <!-- form start -->
                            <form:form action="/auth/manager/add" id="form" method="post" modelAttribute="authManager">
                                <div class="card-body">
                                    <div class="row">
                                        <div class="col-md-6">
                                            <div class="form-group">
                                                <label for="userName">用戶名</label>
                                                <form:input path="userName" cssClass="form-control" placeholder="請輸入用戶名" />
                                            </div>
                                            <div class="form-group">
                                                <label for="password">密碼</label>
                                                <form:password path="password" cssClass="form-control" placeholder="請輸入密碼" />
                                            </div>
                                            <div class="form-group">
                                                <label for="status">狀態</label>
                                                <form:select path="status" cssClass="form-control select2" style="width: 100%;">
                                                    <option value="0" selected="selected">未激活</option>
                                                    <option value="1">激活</option>
                                                    <option value="2">鎖定</option>
                                                    <option value="3">刪除</option>
                                                </form:select>
                                            </div>
                                        </div>
                                        <div class="col-md-6">
                                            <div class="form-group">
                                                <label for="roles">角色</label>
                                                <form:select path="roles" cssClass="select2" multiple="multiple" data-placeholder="請選擇角色" style="width: 100%;">
                                                    <option value="admin" ${authManager.roles.contains("admin")?"selected":""}>
                                                        admin
                                                    </option>
                                                    <option value="editor" ${authManager.roles.contains("editor")?"selected":""}>
                                                        editor
                                                    </option>
                                                </form:select>
                                            </div>
                                            <div class="form-group">
                                                <label for="superuser">是否超級用戶</label>
                                                <form:select path="superuser" cssClass="form-control select2" style="width: 100%;">
                                                    <option value="0" selected="selected">否</option>
                                                    <option value="1">是</option>
                                                </form:select>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <!-- /.card-body -->

                                <div class="card-footer">
                                    <button type="submit" class="btn btn-primary">保存</button>
                                    <a href="/auth/manager/list" type="button" class="btn btn-default">返回列表</a>
                                </div>
                            </form:form>
                        </div>
                        <!-- /.card -->
                    </div>
                </div>
            </div>
            <!-- /.container-fluid -->
        </div>
        <!-- /.content -->
    </div>
    <!-- /.content-wrapper -->

    <jsp:include page="../includes/layout_footer.jsp" />
</div>
<!-- ./wrapper -->
<jsp:include page="../includes/resources_body.jsp" />

<script>
$(function() {
    if (${baseResult.status != null && baseResult.status != 200}) {
        Message.showFail('${baseResult.message}');
    }

    FormValidate.validate(
        'form',
        {
            userName: {
                required: true,
                minlength: 4,
                maxlength: 20
            },
            password: {
                required: true,
                minlength: 6,
                maxlength: 20
            },
            roles: {
                required: true,
                minlength: 1,
                maxlength: 3
            }
        },
        {
            userName: {
                required: " 請輸入用戶名",
                minlength: " 用戶名不能小於4位",
                maxlength: " 用戶名不能大於於20位"
            },
            password: {
                required: " 請輸入密碼",
                minlength: " 密碼不能小於6位",
                maxlength: " 密碼不能大於於20位"
            },
            roles: {
                required: " 請選擇角色",
                minlength: " 至少選擇1個角色",
                maxlength: " 至多選擇3個角色"
            }
        }
    );
})
</script>
<script src="/static/assets/js/select2-utils.js"></script>
<script src="/static/assets/js/message-utils.js"></script>
<script src="/static/assets/js/form-validate-utils.js"></script>
</body>
</html>

其它視圖頁面的代碼修改,請自己完成。

7.實例源碼

實例源碼已經託管到如下地址:


上一篇:搜索功能

上一篇:批量刪除


如果對課程內容感興趣,可以掃碼關注我們的 公眾號QQ群,及時關注我們的課程更新

公眾號 - 光束雲 - work100.net
QQ交流群 - 光束雲 - work100.net

Leave a Reply

Your email address will not be published. Required fields are marked *