搭建自己的博客(二十二):通过ajax提交评论信息,并增加公式编辑功能
编辑功能使用到了ckeditor的MathJax组件。ajax提交评论可以不用刷新浏览器。
1、变化的部分
aaarticlea/png;base64,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" alt="" width="323" height="717" />
2、上代码:
ul.blog-types,ul.blog-dates {
list-style-type: none;
} div.blog:not(:last-child) {
margin-bottom: 2em;
padding-bottom: 1em;
border-bottom: 1px solid #eee;
} div.blog h3 {
margin-top: 0.5em;
} div.blog-info p {
margin-bottom:;
}
div.blog-info p span{
margin-right: 10px;
} div.blog-info-description {
list-style-type: none;
margin-bottom: 1em;
} ul.blog-info-description li {
display: inline-block;
margin-right: 1em;
} div.paginator {
text-align: center;
} div.container {
max-width: 80%;
} div.comment-area{
margin-top: 2em;
} h3.comment-area-title{
border-bottom: 1px solid #ccc;
padding-bottom: 0.4em;
} div.django-ckeditor-widget {
width: 100%;
}
blog.css
{# 引用模板 #}
{% extends 'base.html' %}
{% load staticfiles %} {% block header_extends %}
<link rel="stylesheet" href="{% static 'blog/blog.css' %}">
{# 处理公式 #}
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML'
async></script>
<script type="text/javascript" src="{% static "ckeditor/ckeditor-init.js" %}"></script>
<script type="text/javascript" src="{% static "ckeditor/ckeditor/ckeditor.js" %}"></script>
{% endblock %} {# 标题 #}
{% block title %}
{{ blog.title }}
{% endblock %} {# 内容#}
{% block content %}
<div class="container">
<div class="row">
<div class="col-10 offset-1">
<ul class="blog-info-description">
<h3>{{ blog.title }}</h3>
<li>作者:{{ blog.author }}</li>
{# 时间过滤器让时间按照自己需要的格式过滤 #}
<li>发布日期:{{ blog.created_time|date:"Y-m-d H:i:s" }}</li>
<li>分类:
<a href="{% url 'blogs_with_type' blog.blog_type.pk %}">
{{ blog.blog_type }}
</a>
</li>
<li>阅读({{ blog.get_read_num }})</li>
</ul>
<p class="blog-content">{{ blog.content|safe }}</p> <p>上一篇:
{% if previous_blog %}
<a href="{% url 'blog_detail' previous_blog.pk %}">{{ previous_blog.title }}</a>
{% else %}
<span>没有了</span>
{% endif %}
</p>
<p>下一篇:
{% if next_blog %}
<a href="{% url 'blog_detail' next_blog.pk %}">{{ next_blog.title }}</a>
{% else %}
<span>没有了</span>
{% endif %}
</p>
</div>
</div>
<div class="row">
<div class="col-10 offset-1">
<div class="comment-area">
<h3 class="comment-area-title">提交评论</h3>
{% if user.is_authenticated %}
<form id="comment-form" action="{% url 'update_comment' %}" method="post"
style="overflow: hidden">
{% csrf_token %}
<label for="form-control">{{ user.username }},欢迎评论~</label>
{% for field in comment_form %}
{{ field }}
{% endfor %}
<span id="comment-error" class="text-danger float-left"></span>
<input type="submit" value="评论" class="btn btn-primary float-right">
</form>
{% else %}
您尚未登录,登录之后方可评论
{# 提交登录的时候带上从哪里访问的路径 #}
<a class="btn btn-primary" href="{% url 'login' %}?from={{ request.get_full_path }}">登录</a>
<span> or </span>
<a class="btn-danger btn" href="{% url 'register' %}?from={{ request.get_full_path }}">注册</a>
{% endif %}
</div>
<div class="-comment-area">
<h3 class="comment-area-title">评论列表</h3>
<div id="comment-list">
{% for comment in comments %}
<div>
{{ comment.user.username }}
{{ comment.comment_time|date:"Y-m-d H:i:s" }}
{{ comment.text|safe }}
</div>
{% empty %} {% endfor %}
</div> </div>
</div>
</div>
</div>
{% endblock %} {% block js %}
<script>
$('#comment-form').submit(function () {
// 获取错误框
let comment_error = $('#comment-error');
comment_error.text(''); // 更新数据到textarea
CKEDITOR.instances['id_text'].updateElement();
let comment_text = CKEDITOR.instances['id_text'].document.getBody().getText().trim();
// 判断是否为空
if (!(CKEDITOR.instances['id_text'].document.getBody().find('img')['$'].length !== 0 || comment_text !== '')) {
// 显示错误信息
comment_error.text('评论内容不能为空');
return false;
}
//异步提交
$.ajax({
url: "{% url 'update_comment' %}",
type: 'POST',
data: $(this).serialize(),// 序列化表单值
cache: false, // 关闭缓存
success: function (data) { if (data['status'] === 'SUCCESS') {
console.log(data);
// 插入数据
// es6写法
let comment_html = `<div>${data["username"]} (${data["comment_time"]}): ${data["text"]}</div>`;
$('#comment-list').prepend(comment_html);
// 清空编辑框的内容
CKEDITOR.instances['id_text'].setData('');
} else {
// 显示错误信息
comment_error.text(data['message'])
}
},
error: function (xhr) {
console.log(xhr);
}
});
return false;
})
</script> <script>
$(".nav-blog").addClass("active").siblings().removeClass("active");
</script>
{% endblock %}
blog_detail.html
{# 引用模板 #}
{% extends 'base.html' %}
{% load staticfiles %} {% block header_extends %}
<link rel="stylesheet" href="{% static 'blog/blog.css' %}">
{# 处理公式 #}
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML'
async></script>
<script type="text/javascript" src="{% static "ckeditor/ckeditor-init.js" %}"></script>
<script type="text/javascript" src="{% static "ckeditor/ckeditor/ckeditor.js" %}"></script>
{% endblock %} {# 标题 #}
{% block title %}
{{ blog.title }}
{% endblock %} {# 内容#}
{% block content %}
<div class="container">
<div class="row">
<div class="col-10 offset-1">
<ul class="blog-info-description">
<h3>{{ blog.title }}</h3>
<li>作者:{{ blog.author }}</li>
{# 时间过滤器让时间按照自己需要的格式过滤 #}
<li>发布日期:{{ blog.created_time|date:"Y-m-d H:i:s" }}</li>
<li>分类:
<a href="{% url 'blogs_with_type' blog.blog_type.pk %}">
{{ blog.blog_type }}
</a>
</li>
<li>阅读({{ blog.get_read_num }})</li>
</ul>
<p class="blog-content">{{ blog.content|safe }}</p> <p>上一篇:
{% if previous_blog %}
<a href="{% url 'blog_detail' previous_blog.pk %}">{{ previous_blog.title }}</a>
{% else %}
<span>没有了</span>
{% endif %}
</p>
<p>下一篇:
{% if next_blog %}
<a href="{% url 'blog_detail' next_blog.pk %}">{{ next_blog.title }}</a>
{% else %}
<span>没有了</span>
{% endif %}
</p>
</div>
</div>
<div class="row">
<div class="col-10 offset-1">
<div class="comment-area">
<h3 class="comment-area-title">提交评论</h3>
{% if user.is_authenticated %}
<form id="comment-form" action="{% url 'update_comment' %}" method="post"
style="overflow: hidden">
{% csrf_token %}
<label for="form-control">{{ user.username }},欢迎评论~</label>
{% for field in comment_form %}
{{ field }}
{% endfor %}
<span id="comment-error" class="text-danger float-left"></span>
<input type="submit" value="评论" class="btn btn-primary float-right">
</form>
{% else %}
您尚未登录,登录之后方可评论
{# 提交登录的时候带上从哪里访问的路径 #}
<a class="btn btn-primary" href="{% url 'login' %}?from={{ request.get_full_path }}">登录</a>
<span> or </span>
<a class="btn-danger btn" href="{% url 'register' %}?from={{ request.get_full_path }}">注册</a>
{% endif %}
</div>
<div class="-comment-area">
<h3 class="comment-area-title">评论列表</h3>
<div id="comment-list">
{% for comment in comments %}
<div>
{{ comment.user.username }}
{{ comment.comment_time|date:"Y-m-d H:i:s" }}
{{ comment.text|safe }}
</div>
{% empty %} {% endfor %}
</div> </div>
</div>
</div>
</div>
{% endblock %} {% block js %}
<script>
$('#comment-form').submit(function () {
// 获取错误框
let comment_error = $('#comment-error');
comment_error.text(''); // 更新数据到textarea
CKEDITOR.instances['id_text'].updateElement();
let comment_text = CKEDITOR.instances['id_text'].document.getBody().getText().trim();
// 判断是否为空
if (!(CKEDITOR.instances['id_text'].document.getBody().find('img')['$'].length !== 0 || comment_text !== '')) {
// 显示错误信息
comment_error.text('评论内容不能为空');
return false;
}
//异步提交
$.ajax({
url: "{% url 'update_comment' %}",
type: 'POST',
data: $(this).serialize(),// 序列化表单值
cache: false, // 关闭缓存
success: function (data) { if (data['status'] === 'SUCCESS') {
console.log(data);
// 插入数据
// es6写法
let comment_html = `<div>${data["username"]} (${data["comment_time"]}): ${data["text"]}</div>`;
$('#comment-list').prepend(comment_html);
// 清空编辑框的内容
CKEDITOR.instances['id_text'].setData('');
} else {
// 显示错误信息
comment_error.text(data['message'])
}
},
error: function (xhr) {
console.log(xhr);
}
});
return false;
})
</script> <script>
$(".nav-blog").addClass("active").siblings().removeClass("active");
</script>
{% endblock %}
blog下的views.py
# -*- coding: utf-8 -*-
# @Time : 18-11-20 下午10:47
# @Author : Felix Wang from django import forms
from django.contrib.contenttypes.models import ContentType
from django.db.models import ObjectDoesNotExist
from ckeditor.widgets import CKEditorWidget class CommentForm(forms.Form):
content_type = forms.CharField(widget=forms.HiddenInput)
object_id = forms.IntegerField(widget=forms.HiddenInput)
text = forms.CharField(widget=CKEditorWidget(config_name='comment_ckeditor'),
error_messages={'required': '评论内容不能为空'}) def __init__(self, *args, **kwargs):
if 'user' in kwargs:
self.user = kwargs.pop('user')
super().__init__(*args, **kwargs) # 表单验证
def clean(self):
# 判断用户是否登录
if self.user.is_authenticated:
self.cleaned_data['user'] = self.user
else:
raise forms.ValidationError('用户尚未登录') content_type = self.cleaned_data['content_type']
object_id = self.cleaned_data['object_id']
try:
model_class = ContentType.objects.get(model=content_type).model_class()
model_obj = model_class.objects.get(pk=object_id)
self.cleaned_data['content_object'] = model_obj
except ObjectDoesNotExist as e:
raise forms.ValidationError('评论对象不存在') return self.cleaned_data
comment下的forms.py
from django.shortcuts import render, reverse, redirect
from django.http import JsonResponse
from .models import Comment
from django.contrib.contenttypes.models import ContentType
from .forms import CommentForm
import re
import copy def update_commit(requests):
comment_form = CommentForm(requests.POST, user=requests.user)
if comment_form.is_valid():
comment = Comment()
comment.user = comment_form.cleaned_data['user']
comment.text = comment_form.cleaned_data['text']
comment.content_object = comment_form.cleaned_data['content_object']
comment.save()
# 返回数据
data = {
'status': 'SUCCESS',
'username': comment.user.username,
'comment_time': comment.comment_time.strftime('%Y-%m-%d %H:%M:%S'),
'text': comment.text.strip(),
}
else:
data = {
'status': 'ERROR',
'message': list(comment_form.errors.values())[0][0],
}
return JsonResponse(data)
comment下的biews.py
# -*- coding: utf-8 -*-
# @Time : 18-11-20 下午8:10
# @Author : Felix Wang from django import forms
from django.contrib import auth
from django.contrib.auth.models import User class LoginForm(forms.Form):
username = forms.CharField(label='用户名', required=True,
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入用户名'}))
# widget指定input标签类型
password = forms.CharField(label='密码',
widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': '请输入密码'})) def clean(self): # 验证数据
username = self.cleaned_data['username']
password = self.cleaned_data['password']
user = auth.authenticate(username=username, password=password)
if user is None:
raise forms.ValidationError('用户名或密码错误')
self.cleaned_data['user'] = user # 将验证过的user放入clean_data
return self.cleaned_data class RegisterForm(forms.Form):
# 用户名字段
username = forms.CharField(label='用户名',
max_length=30,
min_length=3,
required=True,
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入用户名'}))
# 邮箱字段
email = forms.EmailField(label='邮箱',
min_length=3,
required=True,
widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': '请输入邮箱'}))
# 密码字段
password = forms.CharField(label='密码',
min_length=6,
required=True,
widget=forms.PasswordInput(
attrs={'class': 'form-control', 'placeholder': '请输入密码'}))
# 再次输入密码
password_again = forms.CharField(label='确认密码',
min_length=6,
required=True,
widget=forms.PasswordInput(
attrs={'class': 'form-control', 'placeholder': '请再输入一次密码'})) def clean_username(self):
username = self.cleaned_data['username']
if User.objects.filter(username=username).exists():
raise forms.ValidationError('用户名已存在')
return username def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise forms.ValidationError('邮箱已存在') return email def clean_password_again(self):
password = self.cleaned_data['password']
password_again = self.cleaned_data['password_again']
if password != password_again:
raise forms.ValidationError('两次输入的密码不一致')
return password_again
myblog下的forms.py
"""
Django settings for myblog project. Generated by 'django-admin startproject' using Django 2.1.3. For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/ For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
""" import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'ea+kzo_5k^6r7micfg@lar1(rfdc08@b4*+w5d11=0mp1p5ngr' # SECURITY WARNING: don't run with debug turned on in production!2.
DEBUG = True ALLOWED_HOSTS = ['*'] # Application definition INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'ckeditor',
'ckeditor_uploader',
'blog.apps.BlogConfig', # 将自己创建的app添加到设置中
'read_statistics.apps.ReadStatisticsConfig', # 注册阅读统计app
'comment.apps.CommentConfig', # 注册评论 ] MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'blog.middleware.mymiddleware.My404', # 添加自己的中间件
] ROOT_URLCONF = 'myblog.urls' TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
] WSGI_APPLICATION = 'myblog.wsgi.application' # Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'myblogs', # 要连接的数据库,连接前需要创建好
'USER': 'root', # 连接数据库的用户名
'PASSWORD': 'felixwang', # 连接数据库的密码
'HOST': '127.0.0.1', # 连接主机,默认本级
'PORT': 3306 # 端口 默认3306
}
} # Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
] # Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/ # LANGUAGE_CODE = 'en-us'
# 语言
LANGUAGE_CODE = 'zh-hans' # TIME_ZONE = 'UTC'
# 时区
TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True # 不考虑时区
USE_TZ = False # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/ STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
] # media
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # 配置ckeditor
CKEDITOR_UPLOAD_PATH = 'upload/' # 自定义参数
EACH_PAGE_BLOGS_NUMBER = 7 # 设置数据库缓存
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_read_num_cache_table',
}
} # ckeditor 代码高亮,以及公式
CKEDITOR_CONFIGS = {
'default': {
'skin': 'moono',
'tabSpaces': 4,
'mathJaxLib': 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML',
'toolbar': (
['div', 'Source', '-', 'Save', 'NewPage', 'Preview', '-', 'Templates'],
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Print',
'SpellChecker', 'Scayt'],
['Undo', 'Redo', '-', 'Find', 'Replace', '-', 'SelectAll', 'RemoveFormat',
'-', 'Maximize', 'ShowBlocks', '-', "CodeSnippet", 'Mathjax', 'Subscript',
'Superscript'],
['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button',
'ImageButton', 'HiddenField'],
['Bold', 'Italic', 'Underline', 'Strike', '-'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],
['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
['Link', 'Unlink', 'Anchor'],
['Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar',
'PageBreak'], ['Styles', 'Format', 'Font', 'FontSize'],
['TextColor', 'BGColor'],),
'extraPlugins': ','.join([
'codesnippet',
'mathjax',
'dialog',
'dialogui',
'lineutils',
]),
},
'comment_ckeditor': {
'toolbar': 'custom',
'toolbar_custom': [
['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript'],
['TextColor', 'BGColor', 'RemoveFormat'],
['NumberedList', 'BulletedList'],
['Link', 'Unlink'],
['Smiley', 'SpecialChar', 'Blockquote'],
],
'width': 'auto',
'height': '',
'tabSpace': 4,
'removePlugins': 'elementspath',
'resize_enabled': False,
}
}
settings.py
搭建自己的博客(二十二):通过ajax提交评论信息,并增加公式编辑功能的更多相关文章
- Django 系列博客(十二)
Django 系列博客(十二) 前言 本篇博客继续介绍 Django 中的查询,分别为聚合查询和分组查询,以及 F 和 Q 查询. 聚合查询 语法:aggregate(*args, **kwargs) ...
- github+hexo搭建自己的博客网站(二)更换主题yilia
开始更换主题,hexo默认的主题是landscape,可以更换为其他的主题yilia主题 详细的可以查看hexo博客的演示:saucxs.github.io 可以查看在github上生成的静态文件:h ...
- 自然语言交流系统 phxnet团队 创新实训 项目博客 (十二)
关于情感词典的学习总结: 情感倾向可认为是主体对某一客体主观存在的内心喜恶,内在评价的一种倾向.它由两个方面来衡量:一个情感倾向方向,一个是情感倾向度. 情感倾向方向也称为情感极性.在微博中,可以理解 ...
- 自然语言交流系统 phxnet团队 创新实训 个人博客 (十二)
在本项目中关于天空盒子的使用的配置方法: 给场景添加天空盒 第二种方式 在菜单栏中选择:Edit->Render Setting,在保证不在选择场景中其它文件的前提下,Inspector面 ...
- github+hexo搭建自己的博客网站(六)进阶配置(搜索引擎收录,优化你的url)
详细的可以查看hexo博客的演示:https://saucxs.github.io/ 绑定了域名: http://www.chengxinsong.cn hexo+github博客网站源码(可以clo ...
- github+hexo搭建自己的博客网站(七)注意事项(避免read.me,CNAME文件的覆盖,手动改github page的域名)
详细的可以查看hexo博客的演示:https://saucxs.github.io/ 绑定域名可以查看:http://www.chengxinsong.cn 可以查看在github上生成的静态文件(如 ...
- 从入门到放弃,.net构建博客系统(二):依赖注入
文章目录:<从入门到放弃,.net构建博客系统> 从入门到放弃,.net构建博客系统(一):系统构建 从入门到放弃,.net构建博客系统(二):依赖注入 上一篇中有讲到项目启动时会进行io ...
- 一步步搭建自己的博客 .NET版(2、评论功能)
前言 这次开发的博客主要功能或特点: 第一:可以兼容各终端,特别是手机端. 第二:到时会用到大量html5,炫啊. 第三:导入博客园的精华文章,并做分类.(不要封我) 第四:做 ...
- 基于hexo+github搭建一个独立博客
一直听说用hexo搭建一个拥有自己域名的博客是很酷炫的事情~,在这十一花上半个小时整个hexo博客岂不美哉. 使用Hexo吸引我的是,其简单优雅, 而且风格多变, 适合程序员搭建个人博客,而且支持多平 ...
随机推荐
- Java基础IO类之File类
大三了,目前基础太差了,重新学习过!代码如下,里面都有详细的解释每一行代码代表的意思~ package IODemo; import java.io.File; import java.io.File ...
- SAS学习笔记47 Macro Quoting
简单来说:Macro Quoting就是将具有特殊功能字符及字母组合的特殊功能隐藏掉.例如:让分号(;)不再表示一个语句的结束,而就是一个普普通通的字符:让GE不再表示大于等于的比较符,而就是两个普普 ...
- session和cookie有什么区别?
1.存储位置不同 cookie的数据信息存放在客户端浏览器上. session的数据信息存放在服务器上. 2.存储容量不同 单个cookie保存的数据<=4KB,一个站点最多保存20个Cooki ...
- VS.NET(C#)--2.8HTML服务器控件
HTML服务器控件 服务器不处理HTML控件,例如:<h1>.<a>超链接.<input>,直接送到客户端,由浏览器呈现. 把HTML控件转换成HTML服务器控件, ...
- Spring/Spring Boot整合Weblogic JMS实战
本文主要介绍weblogic jms的配置,包括JMS 服务器和JMS 模块(连接工厂.队列.远程 SAF 上下文.SAF 导入目的地.SAF 错误处理)的配置:并在Spring/Spring Boo ...
- H5 - 简学
什么是HTML? HTML 是用来描述网页的一种语言. 0.HTML 指的是超文本标记语言 1.HTML 不是一种编程语言,而是一种标记语言 2.标记语言是一套标记标签 3.HTML 使用标记标签来描 ...
- 关于Echarts柱状图点击事件的实现方法
开发过程中,我们经常会碰到这样的需求:在柱状图上,点击某条柱形,调用相应的方法或跳转相应的界面 接下来就详细介绍如何实现柱状图的点击事件,其中maChart是绘图对象 一.简单的点击事件 myChar ...
- RZ70注册SLD
本文的将S4 abap系统向PO JAVA系统中注册. S4 QASERPAP01 NR=60 ASCS=61 PO QASPISAP01 NR=60 SCS=61 http://qaspisap01 ...
- 制作win10系统及安装win10系统
制作win10系统 1.登陆msdn,下载win10系统,打开迅雷下载器,复制完该段代码,直接开始下载,网址:https://msdn.itellyou.cn/ 2.下载软碟通,下载网址:https: ...
- sql server split切割字符串
create FUNCTION [dbo].[dnt_split] ( @splitstring varchar(max), @separator CHAR() = ',' ) RETURNS @sp ...