Ajax — 大事件项目(第四天)

分类管理

添加分类

初步使用弹出层

  • 给 “添加分类” 绑定一个单击事件
  • 单击事件中,使用 layer.open() 实现一个弹出层
    • type: 1, 弹层的类型是页面层
    • title, “添加文字分类”
    • content: ‘字符串,DOM’,
    • area: [‘500px’, ‘250px’]
 // ------------------  点击 添加类别 的时候,显示弹出层 -------------$('#addBtn').click(function () {// layui官网 --> 文档 --> 内置模块 --> 弹出层 --> 独立版本:layer.layui.com// 或者,直接打开弹出层的独立版本网站:layer.layui.com//页面层add_id = layer.open({type: 1,// skin: 'layui-layer-rim', //加上边框title: '添加文章类别',area: ['500px', '250px'], //宽高content: $('#add').html() // 内容,可以使用字符串,也可以使用DOM});});

弹层的内容区,使用DOM

我们可以在html页面中,先准备一个模板(比如id=“add”)。然后open方法的content选项,我们使用 $(’#add’).html()

js代码:

// 点击添加分类按钮,显示弹层$('#showAdd').click(function () {var index = layer.open({type: 1, // 层的类型,1表示页面层title: '添加文章类别', // 标题content: $('#add').html(), // 内容area: ['500px', '250px'], // 宽度高度});});

html中,添加的模板

<!-- 添加的弹层模板 --><script type="text/html" id="add"><form class="layui-form" action="" style="margin-top: 15px; margin-right: 50px;"><!-- 第一行 分类名称 --><div class="layui-form-item"><label class="layui-form-label">分类名称</label><div class="layui-input-block"><input type="text" name="name" required  lay-verify="required" placeholder="请输入标题" autocomplete="off" class="layui-input"></div></div><!-- 第二行 分类别名  --><div class="layui-form-item"><label class="layui-form-label">分类别名</label><div class="layui-input-block"><input type="text" name="alias" required  lay-verify="required" placeholder="请输入标题" autocomplete="off" class="layui-input"></div></div><!-- 第三行 按钮 --><div class="layui-form-item"><div class="layui-input-block"><button class="layui-btn" lay-submit lay-filter="formDemo">确认添加</button><button type="reset" class="layui-btn layui-btn-primary">重置</button></div></div></form></script>

完成添加分类

  • 必须使用事件委托的方案,为添加的表单注册submit事件
  • 发送ajax请求,如果说成功了
    • 关闭弹层
      • 设置弹层的时候,使用变量接受弹层的返回值(每个弹层都有一个索引或者叫做id)
      • layer.close(层的索引或id)
      • 注意弹层索引,要设置为全局变量
    • 从新渲染数据
      • 调用renderHtml()即可渲染

删除分类

接口是需要的id参数是一个动态参数,使用方法: /my/article/deletecate/3

// /my/article/deletecate/:id
// /my/article/deletecate/3   ---- 删除id为3的数据
// /my/article/deletecate/12   ---- 删除id为12的数据
  • 也是,必须使用事件委托的方案,为删除注册单击事件
  • 使用 layer.confirm('是否要删除', {icon: 3, title: '提示'}, function (index) {})
  • 获取分类的id
    • 渲染页面的时候,给每个删除按钮,设置一个data-id属性,值就是当前分类的Id,注意 Id 的 I 是大写的。
    • 事件内部,可以通过事件源获取到id,注意$(this)指向改变
  • 按照接口要求发送ajax请求,完成删除
// -----------------  点击删除,完成删除功能 -----------------
$('body').on('click', '.delete', function () {let that = $(this);layer.confirm('确定删除吗?', { icon: 3, title: '提示' }, function (index) {//do something// 获取idlet id = that.attr('data-id');// ajax请求$.ajax({url: '/my/article/deletecate/' + id,success: function (res) {layer.msg(res.message);if (res.status === 0) {// 删除成功,重新渲染页面renderHtml();}}});layer.close(index); // 关闭弹层});
})

编辑分类

思路:

  • 点击编辑,弹层窗口(样子和添加的窗口一样)
    • 事件委托的方案,为“编辑”按钮注册单击事件(给编辑按钮,添加了一个类 edit)
    • 弹层的JS代码,复制添加的代码,然后修改
    • 弹层的内容,直接复制添加的模板(复制之后,记得修改模板的id和form的id)
  • 为表单赋值
    • 为 “编辑” 按钮,添加三个自定义属性,data-id / data-name / data-alias
    • 表单中,有一个隐藏域(id)
    • 快速为表单元素赋值(必须等弹层出来,然后在为表单赋值)
  • 点击确认修改之后,可以实现修改
    // ------------------ 点击编辑,显示弹出层 ------------------$('body').on('click', '.edit', function () {// 先获取按钮的三个 data-xxx 属性值,他们分别是 id、name、aliaslet id = $(this).attr('data-id');let name = $(this).attr('data-name');let alias = $(this).attr('data-alias');edit_id = layer.open({type: 1,// skin: 'layui-layer-rim', //加上边框title: '编辑文章类别',area: ['500px', '250px'], //宽高content: $('#edit').html(), // 内容,可以使用字符串,也可以使用DOMsuccess: function () {// 弹层成功后,触发的一个函数。在这里快速为表单赋值form.val('editForm', {id, name, alias});}});});

在这里插入图片描述

具体实现:

  1. 在页面渲染的时候,使用{{each}} 循环tr的时候,我们为 “编辑” 按钮,设置三个自定义的属性

    • data-id
    • data-name
    • data-alias
    <!-- 数据列表的模板 -->
    <script type="text/html" id="tpl-cateList">{{each data val}}<tr><td>{{val.name}}</td><td>{{val.alias}}</td><td><button data-id="{{val.Id}}" data-name="{{val.name}}" data-alias="{{val.alias}}" type="button" class="layui-btn layui-btn-xs editCate">编辑</button><button data-id="{{val.Id}}" type="button" class="layui-btn layui-btn-xs layui-btn-danger deleteCate">删除</button></td></tr>{{/each}}
    </script>
    
  2. 点击编辑的时候,获取上述三个自定义属性的值。值,分别设置给弹层的表单中的input

    // 点击编辑的时候,弹层
    $('body').on('click', '.editCate', function () {// 先获取按钮的三个 data-xxx 属性值,他们分别是 id、name、aliaslet id = $(this).attr('data-id');let name = $(this).attr('data-name');let alias = $(this).attr('data-alias');// 弹层editIndex = layer.open({type: 1, // 页面层title: '编辑分类',content: $('#tpl-edit').html(),area: ['500px', '250px'],// 等弹层出来之后,执行下面的success方法success: function () {// 关于 editForm参数,自行查看文档// editForm对应的是表单的lay-filter="editForm"form.val('editForm', {id, name, alias});}});
    });
    
  3. 点击确认修改的时候,获取表单的三项值,处理一下Id,ajax提交,完成修改。

    奇葩的Id,I 是大写的。。。

    // 当编辑的表单提交的时候,发送ajax请求,完成编辑
    // $('#form-edit').submit(); // 直接注册不行,必须使用事件委托
    $('body').on('submit', '#form-edit', function (e) {e.preventDefault();// console.log($(this).serialize()); // name=xxx&alias=16&id=1// var data = $(this).serialize().replace('id', 'Id');// console.log($(this).serializeArray());var data = $(this).serializeArray();data[0].name = 'Id';console.log(data);// console.log(data);$.post('/my/article/updatecate', data, function (res) {if (res.status !== 0) {return layer.msg(res.message);}layer.msg('更新分类成功');// 1. 从新渲染页面renderHtml();// 2. 关闭弹层layer.close(editIndex);});
    

})

## 提交一下`git add .``git commit -m '完成了文章分类的增删改查'`# 文章管理## 文章列表- 准备工作(创建页面、挂好链接、引入所需的css和js文件)- 页面布局 - 搜索区- 找到“组装行内表单”- 下拉框没有显示,需要把 layui.all.js 的加载放到页面的后面- 表格区- 自行复制代码,然后跳转宽度、设置按钮- 分页区
- 定义渲染文章列表的函数 (renderArticle)
- 定义renderArticle函数,函数内容,发送ajax请求,获取数据,并调用template渲染
- ajax请求参数,我们先定义成全局变量
- 通过模板引擎提供的过滤器功能,对时间进行处理## 删除文章- 给删除按钮,添加一个data-id属性,值就是当前文章的id
- 给删除按钮添加一个类 delete
- JS代码中,事件委托的方案,给删除注册单击事件
- 事件内部,获取id
- 询问是否要删除
- 如果确定删除,则发送ajax请求,完成删除
- 完成删除之后,从新渲染页面## 添加文章- 准备工作```html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><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/lib/cropper/cropper.css"><link rel="stylesheet" href="/assets/css/article/publish.css"><script src="/assets/lib/jquery.js"></script><!-- 剪裁用的js --><script src="/assets/lib/cropper/Cropper.js"></script><script src="/assets/lib/cropper/jquery-cropper.js"></script><!-- 内容区的富文本编辑器用的js --><script src="/assets/lib/tinymce/tinymce.min.js"></script><script src="/assets/lib/tinymce/tinymce_setup.js"></script><!-- 模板引擎js --><script src="/assets/lib/template-web.js"></script><script src="/assets/js/common.js"></script><script src="/assets/js/article/publish.js"></script>
</head>
<body><script src="/assets/lib/layui/layui.all.js"></script>
</body>
</html>
  • 页面布局

    • 使用卡片面板
    • 内容区放表单
    • 表单的内容区
      • 去 “富文本和封面.md” 中,复制html代码
      • 在自己的js中,调用一个 initEditor() 函数,即可实现
    • 表单的图片裁剪区
      • 去 “富文本和封面.md” 中,复制html代码
      • 去 “富文本和封面.md” 中,复制css代码
      • 去 “富文本和封面.md” 中,复制js代码,实现初始化剪裁效果
    • 按钮区
      • 不要使用重置按钮
    • 使用两个提交按钮,修改里面的文字为 “发布”和“存为草稿”即可
  • 介绍一下富文本编辑器

    • 富文本编辑,也叫做在线文本编辑器、或在线html编辑器
    • 它就是一个插件,允许我们在页面中,像编辑word一样来编辑你的文章内容
    • 常用的富文本编辑器举例
      • tinymce (我们项目中使用的,可制定性比较高)
      • ueditor(百度的产品)
      • ckeditor (外国的)
      • kindeditor(博客园使用了它)
    • 一般在发布文章的时候使用它。

发布文章的具体实现:

  • 获取所有的分类,渲染到下拉框

    • ajax请求之后,获取到分类
    • 使用模板引擎渲染select框
    • 动态添加select框之后,发现页面中的下拉框看不见了
      • 解决办法是:使用 form.render() 方法更新渲染即可
  • 点击发布的时候,让状态是已发布,点击存为草稿,让状态是草稿

    var state = '已发布';
    // 给发布和存为草稿分别注册一个单击事件
    $('button:contains("发布")').click(function () {state = '已发布';
    });
    $('button:contains("存为草稿")').click(function () {state = '草稿';
    });
    
  • 把表单中,每个表单元素的name检查一下,因为FormData是根据name获取值的

  • 点击发布或存为草稿的时候,同样会触发表单提交事件

    • 收集表单各项数据 (title/content/cate_id)
    • 手动追加 state
    • 完成图片裁剪,并将得到的图片追加到FormData中
      • 裁剪之后,完成ajax请求,提交数据到接口,从而完成添加

编辑文章

  • 复制添加文章页为编辑页面(edit.html)

  • 文章列表页,给“编辑挂超链接”,跳转到编辑页面,并挂id参数

    • id在编辑页面可以区分当前修改的是那篇文章
  • 到编辑页面的js中

    • 获取地址栏的id
    • 根据id获取当前文章
    • 为表单快速赋值
    • 将剪裁区的图片换成当前文章原始的图片

其他JS代码参照添加文章的代码即可

分页

  • 文章列表页,加载laypage模块
  • 编写渲染分页的函数 (renderPage)
  • 渲染完文章列表之后,马上渲染分页
  • renderPage函数
    • 根据官方文档,生成分页效果
    • jump事件中,修改请求参数中的pagenum和pagesize,并重新渲染列表

搜索

  • 先处理好搜索区的两个下拉框
  • 监听表单的提交事件
    • 获取下拉框的值
    • 修改获取文章列表的请求参数
    • 重新渲染文章列表

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248012.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis学习(四)

一、Redis 键(key) 1、Redis 键命令用于管理 redis 的键。 2、Redis 键命令的基本语法如下&#xff1a;redis 127.0.0.1:6379> COMMAND KEY_NAME 3、常用key命令 keys * 获取所有的keyselect 0 选择第一个库move myString 1 将当前的数据库key移动到某个…

TCP/IP(三):IP协议相关技术

在前两篇文章中&#xff0c;我分别介绍了数据链路层和网络层的IP协议。虽然这个系列教程的重点是搞定 TCP/IP&#xff0c;不过不用着急&#xff0c;本文简要介绍完与 IP 协议相关的技术&#xff0c;下一篇文章就会正式、详细的介绍 传输层与 TCP 协议。这篇文章会介绍 DNS、ARP…

Node — 第一天

Node-01 会 JavaScript&#xff0c;就能学会 Node.js&#xff01;&#xff01;&#xff01; **Node.js 的官网地址&#xff1a; ** Node.js 的学习路径&#xff1a; JavaScript 基础语法 Node.js 内置 API 模块&#xff08;fs、path、http等&#xff09; 第三方 API 模块&…

TCP/IP(四):TCP 与 UDP 协议简介

从本章开始&#xff0c;我们开始介绍最重要的传输层。传输层位于 OSI 七层模型的第四层&#xff08;由下往上&#xff09;。顾名思义&#xff0c;传输层的主要作用是实现应用程序之间的通信。网络层主要是保证不同数据链路下数据的可达性&#xff0c;至于如何传输数据则是由传输…

Node — 第二天

http模块 搭建服务器的步骤 ① 导入 http 模块 ② 创建 web 服务器实例 ③ 为服务器实例绑定 request 事件&#xff0c;监听客户端的请求 ④ 启动服务器 // ① 导入 http 模块 const http require(http);// ② 创建 web 服务器实例 const server http.createServer();/…

TCP/IP(五):TCP 协议详解

上一节 中讲过&#xff0c;TCP 协议是面向有连接的协议&#xff0c;它具有丢包重发和流量控制的功能&#xff0c;这是它区别于 UDP 协议最大的特点。本文就主要讨论这两个功能。 数据包重发 数据发送 丢包重发的前提是发送方能够知道接收方是否成功的接收了消息。所以&#…

TCP/IP(六):HTTP 与 HTTPS 简介

本文是准备面试过程中网络部分总结整理的最后一篇文章&#xff0c;主要介绍以下知识&#xff1a; HTTP 协议概述POST 请求和 GET 请求Cookie 和 Session数据传输时的加密HTTPS 简介 HTTP 协议 在 OSI 七层模型中&#xff0c;HTTP 协议位于最顶层的应用层中。通过浏览器访问网…

Node — 第三天

模块化 什么是模块化 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层把系统划分成若干模块的过程。 对于整个系统来说&#xff0c;模块是可组合、分解和更换的单元。 生活中的模块化 编程中的模块化 编程领域中的模块化&#xff0c;就是遵守固定的规则&#xff0c;…

FireDAC 中文字段过滤问题

当使用 FireDAC Filter 过滤数据的时候&#xff0c;通常这样写&#xff1a; FDMemTable.Filtered : False; FDMemTable1.Filter : 姓名 string(edtFilter.Text).QuotedString; FDMemTable.Filtered : True; 将会报错&#xff1a;[FireDAC][Stan][Eval]-107. Invalid characte…

Express — 使用步骤

Express Express 介绍安装搭建服务器的步骤express提供的新方法GET接口 获取GET中的请求参数 POST接口 获取POST请求提交的数据 中间件原理中间件语法中间件初体验&#xff08;设置响应头&#xff09;中间件开放静态资源中间件接收POST请求体中间件返回404页面 express 介绍 E…

大模型工具_Langchain-Chatchat

https://github.com/chatchat-space/Langchain-Chatchat 原Langchain-ChatGLM 1 功能 整体功能&#xff0c;想解决什么问题 基于 Langchain 与 ChatGLM 等LLM模型&#xff0c;搭建一套针对中文场景与开源模型&#xff0c;界面友好、可离线运行的知识库问答解决方案。 当前解决…

iOS 键盘风格详解UIKeyboardType

一、键盘风格 UIKit框架支持8种风格键盘。 [java] view plaincopy print?typedef enum { UIKeyboardTypeDefault, // 默认键盘&#xff1a;支持所有字符 UIKeyboardTypeASCIICapable, // 支持ASCII的默认键盘 UIKeyboardTypeNu…

Node — 第四天(Promise与路由)

Promise - ES6新对象 Promise能够处理异步程序。 回调地狱 JS中或node中&#xff0c;都大量的使用了回调函数进行异步操作&#xff0c;而异步操作什么时候返回结果是不可控的&#xff0c;如果我们希望几个异步请求按照顺序来执行&#xff0c;那么就需要将这些异步操作嵌套起来…

winform datagridview控件使用

最近做项目时&#xff0c;显示查询结果总需要绑定到datagridview控件上显示&#xff0c;总结了给datagridview绑定数据的方式&#xff0c;以及导出datagridview数据到excel表格&#xff0c;如有错误请多指教 1.直接绑定数据源&#xff0c;可以绑定的数据格式有List<T>,Da…

Node — 第五天

1. MySQL数据库 phpstudy 数据库服务器及图形化软件 软件链接 链接&#xff1a;https://pan.baidu.com/s/1F8wdoMstHAJkINfDKDejsw 提取码&#xff1a;xl3k 数据库对于我们前端同学来说&#xff0c;就是一个了解。 对于不会变化的数据&#xff08;省、市、县&#xff09;&…

iOS10 权限访问崩溃

手机升级了 iOS10 Beta&#xff0c;然后用正在开发的项目 装了个ipa包&#xff0c;发现点击有关 权限访问 直接Crash了&#xff0c;并在控制台输出了一些信息&#xff1a; This app has crashed because it attempted to access privacy-sensitive data without a usage descr…

Node — 第六天(前后端分离)及(身份验证)

综合应用服务端知识点搭建项目 下载安装所需的第三方模块 npm init -y npm i express cors mysql # express 用于搭建服务器 # cors 用于解决跨域 # mysql 用于操作数据库# 后面用到什么&#xff0c;再下载创建app.js 之前&#xff0c;我们开启一个服务器&#xff0c;js文件…

继承上机作业

1、实现如下类之间的继承关系&#xff0c;并编写Music类来测试这些类 2、编写一个Java应用程序&#xff0c;该程序包括3个类&#xff1a;Monkey类、People类和主类E。要求&#xff1a; (1) Monkey类中有个构造方法&#xff1a;Monkey (String s)&#xff0c;并且有个public voi…

ApplePay集成教程

Apple Pay运行环境&#xff1a;iPhone6以上设备&#xff0c;操作系统最低iOS9.0以上&#xff0c;部分信息设置需要iOS9.2以上。目前还不支持企业证书添加。 环境搭建好后可以在模拟器上面运行&#xff0c;xcode7.2.1iPhone6SP9.2系统下&#xff0c;系统会绑定几种虚拟的银行卡…

Node — 第七天 (大事件项目接口实现一)

关于JS错误处理 node中和mysql中的错误处理 node和MySQL提供的方法&#xff0c;已经对错误信息进行了封装&#xff0c;只需要使用 err.message 即可获取到错误信息。 比如&#xff1a; const fs require(fs); // 读取一个不存在的文件 fs.readFile(abcd.txt, (err, data) …