大事件项目第三天(二)

简介: 大事件项目第三天(二)

五、删除文章

fff7f948764142729ef513723ac6ff91.png


1、实现删除文章的功能

为删除按钮绑定 btn-delete 类名和 data-id 自定义属性

html 结构( /article/art_list.html )

<button type="button" class="layui-btn layui-btn-danger layui-btn-xs btn-delete" data-id="{{$value.Id}}">删除</button>


通过代理的形式,为删除按钮绑定点击事件处理函数

  • 弹出确认取消框提示用户
  • 用户点击确认,发送请求,删除当前文章,携带文章id
  • 请求成功之后,获取最新的文章列表信息
  • 关闭当前弹出层

js 代码( /assets/js/article/art_list.js )

$('tbody').on('click', '.btn-delete', function() {
    // 获取到文章的 id
    var id = $(this).attr('data-id')
    // 询问用户是否要删除数据
    layer.confirm('确认删除?', { icon: 3, title: '提示' }, function(index) {
        $.ajax({
            method: 'GET',
            url: '/my/article/delete/' + id,
            success: function(res) {
                if (res.status !== 0) {
                    return layer.msg('删除文章失败!')
                }
                layer.msg('删除文章成功!')
                initTable()
            }
        })
        layer.close(index)
    })
})


2、解决删除文章时的小 Bug

问题:删除后,页码值虽然正常,但是当前页码的数据没有渲染出来

解决:

  • 判断删除后,页面上是否还有数据
  • 判断当前页面的删除按钮的长度是否等于1
  • 如果等于1,那么我们让当前页码-1即可,如果不等于1,不用处理


js 代码( /assets/js/article/art_list.js )

$('tbody').on('click', '.btn-delete', function() {
    // 获取删除按钮的个数
    var len = $('.btn-delete').length
    // 获取到文章的 id
    var id = $(this).attr('data-id')
    // 询问用户是否要删除数据
    layer.confirm('确认删除?', { icon: 3, title: '提示' }, function(index) {
        $.ajax({
            method: 'GET',
            url: '/my/article/delete/' + id,
            success: function(res) {
                if (res.status !== 0) {
                    return layer.msg('删除文章失败!')
                }
                layer.msg('删除文章成功!')
                // 当数据删除完成后,需要判断当前这一页中,是否还有剩余的数据
                // 如果没有剩余的数据了,则让页码值 -1 之后,
                // 再重新调用 initTable 方法
                // 4
                if (len === 1) {
                    // 如果 len 的值等于1,证明删除完毕之后,页面上就没有任何数据了
                    // 页码值最小必须是 1
                    q.pagenum = q.pagenum === 1 ? 1 : q.pagenum - 1
                }
                initTable()
            }
        })
        layer.close(index)
    })
})


六、发布文章

2cbf9e580be542ccb7ee4e27103b9e70.png


1、创建文章发布页面的基本结构

新建 /article/art_pub.html 页面结构

利用卡片区域进行结构布局

html 结构( /article/art_pub.html )

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <link rel="stylesheet" href="/assets/lib/layui/css/layui.css" />
        <link rel="stylesheet" href="/assets/css/article/art_pub.css" />
    </head>
    <body>
        <!-- 卡片区域 -->
        <div class="layui-card">
            <div class="layui-card-header">写文章</div>
            <div class="layui-card-body">
                卡片式面板面板通常用于非白色背景色的主体内<br />
                从而映衬出边框投影
            </div>
        </div>
    </body>
    <script src="/assets/lib/layui/layui.all.js"></script>
    <script src="/assets/lib/jquery.js"></script>
    <script src="/assets/js/baseAPI.js"></script>
    <script src="/assets/js/article/art_pub.js"></script>
</html>


新建 /assets/css/article/art_pub.css 样式文件

css 样式( /assets/css/article/art_pub.css )

html,
body {
    margin: 0;
    padding: 0;
}
body {
    padding: 15px;
    background-color: #f2f3f5;
}


新建 /assets/js/article/art_pub.js 脚本文件


2、新建基本的表单结构

自上而下 文章标题 → 文章类别 → 文章内容 → 文章封面 → 表单操作按钮

html 结构( /article/art_pub.html )

<!-- 发布文章的表单 -->
<form class="layui-form">
    <!-- 第一行 -->
    <div class="layui-form-item">
        <label class="layui-form-label">文章标题</label>
        <div class="layui-input-block">
            <input
                   type="text"
                   name="title"
                   required
                   lay-verify="required"
                   placeholder="请输入标题"
                   autocomplete="off"
                   class="layui-input"
                   />
        </div>
    </div>
</form>


3、渲染文章类别对应的下拉选择框结构

第二行右侧内容应该是下拉选择框 select,必填项,里面的内容是动态进行获取的

html 结构( /article/art_pub.html )

<!-- 第二行 -->
<div class="layui-form-item">
    <label class="layui-form-label">文章类别</label>
    <div class="layui-input-block">
        <select name="cate_id" lay-verify="required"></select>
    </div>
</div>


导入 art-template

html 结构( /article/art_pub.html )

<script src="/assets/lib/template-web.js"></script>


定义模板结构,多个条目,利用列表渲染

html 结构( /article/art_pub.html )

<script type="text/html" id="tpl-cate">
  <option value="">请选择文章类别</option>
  {{each data}}
  <option value="{{$value.Id}}">{{$value.name}}</option>
  {{/each}}
</script>


定义 initCate 方法,请求文章类别的列表,利用模板引擎渲染到页面

js 代码( /assets/js/article/art_pub.js )

$(function() {
    const form = layui.form;
    const layer = layui.layer;
    // 获取文章分类
    const initCate = () => {
        $.ajax({
            type: "GET",
            url: "/my/article/cates",
            success: function (res) {
                if (res.status !== 0) {
                    return layer.msg("初始化文章分类失败!");
                }
                // 调用模板引擎,渲染分类的下拉菜单
                var htmlStr = template("tpl-cate", res);
                $("[name=cate_id]").html(htmlStr);
                // 一定要记得调用 form.render() 方法 否则看不到页面的变化
                form.render();
            },
        });
    };
    initCate();
})


4、渲染富文本编辑器

添加如下的 layui 表单行

html 结构( /article/art_pub.html )

<div class="layui-form-item">
    <!-- 左侧的 label -->
    <label class="layui-form-label">文章内容</label>
    <!-- 为富文本编辑器外部的容器设置高度 -->
    <div class="layui-input-block" style="height: 400px;">
        <!-- 重要:将来这个 textarea 会被初始化为富文本编辑器 -->
        <textarea name="content"></textarea>
    </div>
</div>


导入富文本必须的 script 脚本

html 结构( /article/art_pub.html )

<!-- 富文本 -->
<script src="/assets/lib/tinymce/tinymce.min.js"></script>
<script src="/assets/lib/tinymce/tinymce_setup.js"></script>


调用 initEditor() 方法,初始化富文本编辑器

js 代码( /assets/js/article/art_pub.js )

// 初始化富文本编辑器
initEditor()


5、渲染封面裁剪区域

<head> 中导入 cropper.css 样式表

html 结构( /article/art_pub.html )

<link rel="stylesheet" href="/assets/lib/cropper/cropper.css" />


<body> 的结束标签之前,按顺序导入如下的 js 脚本

html 结构( /article/art_pub.html )

<script src="/assets/lib/jquery.js"></script>
<script src="/assets/lib/cropper/Cropper.js"></script>
<script src="/assets/lib/cropper/jquery-cropper.js"></script>


在表单中,添加如下的表单行结构

html 结构( /article/art_pub.html )

<div class="layui-form-item">
    <!-- 左侧的 label -->
    <label class="layui-form-label">文章封面</label>
    <!-- 选择封面区域 -->
    <div class="layui-input-block cover-box">
        <!-- 左侧裁剪区域 -->
        <div class="cover-left">
            <img id="image" src="/assets/images/sample2.jpg" alt="" />
        </div>
        <!-- 右侧预览区域和选择封面区域 -->
        <div class="cover-right">
            <!-- 预览的区域 -->
            <div class="img-preview"></div>
            <!-- 选择封面按钮 -->
            <button type="button" class="layui-btn layui-btn-danger">选择封面</button>
        </div>
    </div>
</div>


美化的样式

css 样式( /assets/css/article/art_pub.css )

/* 封面容器的样式 */
.cover-box {
    display: flex;
}
/* 左侧裁剪区域的样式 */
.cover-left {
    width: 400px;
    height: 280px;
    overflow: hidden;
    margin-right: 20px;
}
/* 右侧盒子的样式 */
.cover-right {
    display: flex;
    flex-direction: column;
    align-items: center;
}
/* 预览区域的样式 */
.img-preview {
    width: 200px;
    height: 140px;
    background-color: #ccc;
    margin-bottom: 20px;
    overflow: hidden;
}


实现基本裁剪效果

js 代码( /assets/js/article/art_pub.js )

// 1. 初始化图片裁剪器
var $image = $('#image')
// 2. 裁剪选项
var options = {
    aspectRatio: 400 / 280,
    preview: '.img-preview'
}
// 3. 初始化裁剪区域
$image.cropper(options)


6、渲染提交按钮区域

html 结构( /article/art_pub.html )

<!-- 第五行 -->
<div class="layui-form-item">
    <div class="layui-input-block">
        <button class="layui-btn" lay-submit>发布</button>
        <button class="layui-btn layui-btn-primary" lay-submit>存为草稿</button>
    </div>
</div>


7、点击选择封面按钮打开文件选择框

修改 UI 结构,为 选择封面 按钮添加 id,并且在按钮后面添加 文件选择框

html 结构( /article/art_pub.html )

<!-- 选择封面按钮 -->
<button type="button" class="layui-btn layui-btn-danger" id="btnChooseImage">选择封面</button>
<!-- 隐藏的文件选择框 -->
<input type="file" id="coverFile" style="display: none;" accept="image/png,image/jpeg,image/gif" />


为选择封面的按钮,绑定点击事件处理函数

js 代码( /assets/js/article/art_pub.js )

$('#btnChooseImage').on('click', function() {
    $('#coverFile').click()
})


8、将选择的图片设置到裁剪区域中
  • 监听 coverFilechange 事件,获取用户选择的文件列表
  • 跟进文件,创建对应的 URL 地址
  • 为裁剪区域重新设置图片
  • 销毁旧的裁剪区域
  • 重新设置图片路径
  • 重新初始化裁剪区域


js 代码( /assets/js/article/art_pub.js )

// 监听 coverFile 的 change 事件,获取用户选择的文件列表
$('#coverFile').on('change', function(e) {
    // 获取到文件的列表数组
    var files = e.target.files
    // 判断用户是否选择了文件
    if (files.length === 0) {
        return
    }
    // 根据文件,创建对应的 URL 地址
    var newImgURL = URL.createObjectURL(files[0])
    // 为裁剪区域重新设置图片
    $image
        .cropper('destroy') // 销毁旧的裁剪区域
        .attr('src', newImgURL) // 重新设置图片路径
        .cropper(options) // 重新初始化裁剪区域
})


9、分析发布文章的实现步骤

为 存为草稿 按钮添加 id 属性

html 结构( /article/art_pub.html )

<button class="layui-btn layui-btn-primary" lay-submit id="btnSave2">
  存为草稿
</button>


定义文章的发布状态

js 代码( /assets/js/article/art_pub.js )

let art_state = '已发布'


为存为草稿按钮,绑定点击事件处理函数

js 代码( /assets/js/article/art_pub.js )

$('#btnSave2').on('click', function() {
    art_state = '草稿'
})


10、基于Form表单创建FormData对象

为发布文章的 Form 表单添加 id 属性

html 结构( /article/art_pub.html )

<form class="layui-form" id="form-pub"></form>


为表单绑定 submit 提交事件

  • 阻止表单默认提交行为
  • 基于 form 表单,快速创建一个 FormData 对象
  • 将文章的发布状态,存到 FormData 对象中


js 代码( /assets/js/article/art_pub.js )

$('#form-pub').on('submit', function(e) {
    // 1. 阻止表单的默认提交行为
    e.preventDefault()
    // 2. 基于 form 表单,快速创建一个 FormData 对象
    var fd = new FormData($(this)[0]);
    // 3. 将文章的发布状态,存到 fd 中
    fd.append('state', art_state)
})


11、将裁剪后的封面追加到FormData对象中
  • 将裁剪后的图片输出成一个文件
  • 把文件追加到 formData 中即可

js 代码( /assets/js/article/art_pub.js )

// 为表单绑定 submit 提交事件
$('#form-pub').on('submit', function(e) {
    ...
    // 4. 将封面裁剪过后的图片,输出为一个文件对象
    $image
        .cropper('getCroppedCanvas', {
        // 创建一个 Canvas 画布
        width: 400,
        height: 280
    })
        .toBlob(function(blob) {
        // 将 Canvas 画布上的内容,转化为文件对象
        // 得到文件对象后,进行后续的操作
        // 5. 将文件对象,存储到 fd 中
        fd.append('cover_img', blob)
        // 6. 发起 ajax 数据请求
    })
})


12、发起Ajax请求实现发布文章的功能
  • 定义一个发布文章的方法
  • 注意:如果是提交的是FormData格式数据,需要添加 contentType:false ,processData:false


js 代码( /assets/js/article/art_pub.js )

function publishArticle(fd) {
    $.ajax({
        method: 'POST',
        url: '/my/article/add',
        data: fd,
        // 注意:如果向服务器提交的是 FormData 格式的数据,
        // 必须添加以下两个配置项
        contentType: false,
        processData: false,
        success: function(res) {
            if (res.status !== 0) {
                return layer.msg('发布文章失败!')
            }
            layer.msg('发布文章成功!')
            // 发布文章成功后,跳转到文章列表页面
            location.href = '/article/art_list.html'
        }
    })
}


把裁剪的图片追加到 FormData 对象中之后,调用 publishArticle 方法

js 代码( /assets/js/article/art_pub.js )

// 为表单绑定 submit 提交事件
$('#form-pub').on('submit', function(e) {
    // 1. 阻止表单的默认提交行为
    e.preventDefault()
    // 2. 基于 form 表单,快速创建一个 FormData 对象
    var fd = new FormData($(this)[0])
    // 3. 将文章的发布状态,存到 fd 中
    fd.append('state', art_state)
    // 4. 将封面裁剪过后的图片,输出为一个文件对象
    $image
        .cropper('getCroppedCanvas', {
        // 创建一个 Canvas 画布
        width: 400,
        height: 280
    })
        .toBlob(function(blob) {
        // 将 Canvas 画布上的内容,转化为文件对象
        // 得到文件对象后,进行后续的操作
        // 5. 将文件对象,存储到 fd 中
        fd.append('cover_img', blob)
        // 6. 发起 ajax 数据请求
        publishArticle(fd)
    })
})


13、将开发完成的项目代码推送到GitHub
  1. 运行 git add . 命令
  2. 运行 git commit -m "完成文章管理相关功能的开发" 命令
  3. 运行 git push -u origin article 命令
  4. 运行 git checkout master 命令
  5. 运行 git merge article 命令
  6. 运行 git push 命令








目录
相关文章
|
20天前
|
搜索推荐 数据挖掘 数据管理
六月惊喜 | 事件分析 Plus 上线
6 月,<自定义分析>千呼万唤始出来,同时我们还增加了<书签管理>、<权限管理>模块
六月惊喜 | 事件分析 Plus 上线
|
3月前
|
前端开发 程序员
老程序员分享:jquerytooltip事件
老程序员分享:jquerytooltip事件
16 0
|
4月前
|
存储 SQL 前端开发
🚀经常发文章的你是否想过定时发布是咋实现的?🚀
🚀经常发文章的你是否想过定时发布是咋实现的?🚀
|
4月前
|
前端开发 BI
项目提交按钮没防抖,差点影响了验收
项目提交按钮没防抖,差点影响了验收
|
10月前
|
小程序 程序员
情侣小程序2.0版本已提上日程
情侣小程序2.0版本已提上日程
62 0
情侣小程序2.0版本已提上日程
|
9月前
|
算法 网络协议 Java
双非本科跨专业5面京东,8600小时后收到通知,流下喜悦泪水
自身情况: 1、本科双非,硕士211,均不是计算机相关专业。 2、研究生期间从事的科研项目,材料方向,没有java或者其它编程相关的项目。 3、本科参加比赛较多,电子设计大赛,大学生数学竞赛等,没有程序相关的比赛经历。 4、由于身边的人大多数从事程序员行业,自己其实也很纠结,于是疫情期间(2020年4月份)开始零基础看Java,由于个人原因,5、6月份也没怎么学习,断断续续刷了点题(真后悔5、6月份没好好刷题)。还狠狠地梳理了一遍知识体系
|
前端开发 JavaScript API
大事件项目超详细讲解(可跟做练手项目)(一)
大事件项目超详细讲解(可跟做练手项目)
993 0
大事件项目超详细讲解(可跟做练手项目)(一)
新增闯关模式,邀请好朋友测试
计划为精致1010新增闯关模式,先把游戏原型做出来了,希望朋友们可以先行体验,并给予反馈和意见。
89 0
|
JavaScript 前端开发 容器
大事件项目第三天(一)
大事件项目第三天
103 0
大事件项目第三天(一)
|
缓存 JavaScript 前端开发
大事件项目第二天(一)
大事件项目第二天
116 0
大事件项目第二天(一)