摘要:而且上一篇文章中,也已经实现了一个基本的用户管理列表页面。接着上一篇,完善用户管理,实现增删改。为了用户体验,增加和修改用户信息的表单,都放在弹窗中进行。
定义用户增加窗口:app/luter/view/sys/user/UserAdd.js</>复制代码
经过前面几篇文章的介绍,一个基本的MVC结构应该是具备了。而且上一篇文章中,也已经实现了一个基本的用户管理列表页面。接着上一篇,完善用户管理,实现增删改。为了用户体验,增加和修改用户信息的表单,都放在弹窗中进行。避免跳转页面。
</>复制代码
Ext.define("luter.view.sys.user.UserAdd", {
extend: "Ext.window.Window",//扩展window组件
alias: "widget.useraddview",
requires: [],
constrain: true,//约束窗体弹出,别出浏览器可视范围
modal: true,//模态
maximizable: true,//可以最大化
iconCls: baseConfig.appicon.add,//图标
layout: "fit",//自适应布局
width: 700,
autoHeight: true,//自适应高度
viewModel: {
data: {
title: ""
}
},
bind: {
title: "新增用户: " + "{title}"//绑定这个空间的title属性上
},
initComponent: function () {
var me = this;
//加入一个表单,表单内元素通过loadView方法添加
me.items = [{
xtype: "form",
width: 700,
autoHeight: true,
fieldDefaults: {
labelAlign: "right",
labelStyle: "font-weight:bold;"
},
border: false
}]
//操作按钮直接加载window上
me.buttons = ["->", {
text: "新增",
cls: "green-btn",
iconCls: baseConfig.appicon.add,
handler: function () {
var form = this.down("form");
if (form.isValid()) {
form.submit({
url: "sys/user/add",
method: "POST",
waitTitle: "提示",
waitMsg: "正在提交数据,请稍后 ……",
success: function (form, action) {//添加成功后提示消息,并且刷新用户列表数据
me.close();
DealAjaxResponse(action.response);
Ext.data.StoreManager.lookup("UserStore").load();
},
failure: function (form, action) {
DealAjaxResponse(action.response);
}
});
} else {
toast({
msg: "表单填写错误,请确认"
})
}
},
scope: this
}, "-", {
text: "放弃",
cls: "red-btn",
iconCls: baseConfig.appicon.undo,
handler: function () {
me.close();
},
scope: this
}]
me.callParent(arguments);
},
//form表单的渲染在这里完成,目的是可以通过创建操作传入参数
loadView: function (config) {
var formCmp = this.getComponent(0);
formCmp.add([{
columnWidth: 1,
layout: "form",
items: [{
xtype: "textfield",
fieldLabel: baseConfig.model.user.username,
name: "username",
maxLength: 250,
maxLengthText: "请输入{0}个字以内",
emptyText: "登录用的用户名",
bind: "{title}",//mvvm数据绑定,输入的时候同步就显示在win的title上了
allowBlank: false,
flex: 1
},
{
xtype: "textfield",
fieldLabel: baseConfig.model.user.real_name,
name: "real_name",
maxLength: 10,
maxLengthText: "请输入{0}个字以内",
emptyText: "真实姓名",
allowBlank: false,
flex: 1
}
]
}]);
}
});
添加用户的触发动作是在用户列表页面的添加按钮,所以,还需要修改一下用户列表页面里对应位置,加入触发动作,如下:
</>复制代码
。。。。。
me.dockedItems = [{
xtype: "toolbar",
items: [{
text: "添加",
iconCls: baseConfig.appicon.add,
tooltip: "添加",
handler: function () {
//create的时候,js会动态加载进来。
var win = Ext.create("luter.view.sys.user.UserAdd", {
animateTarget: this//以这个按钮为锚点动画打开win
});
win.loadView();//给form加入元素,可以在这里传入一些参数给将要打开的添加页面
win.show();//显示这个窗体
}
}]
}]
。。。。。。
定义用户信息修改窗口:app/luter/view/sys/user/UserEdit.js
</>复制代码
Ext.define("luter.view.sys.user.UserEdit", {
extend: "Ext.window.Window",//扩展window组件
alias: "widget.usereditview",
requires: [],
constrain: true,//约束窗体弹出,别出浏览器可视范围
modal: true,//模态
maximizable: true,//可以最大化
iconCls: baseConfig.appicon.update,//图标
layout: "fit",//自适应布局
width: 700,
autoHeight: true,//自适应高度
initComponent: function () {
var me = this;
//加入一个表单,表单内元素通过loadView方法添加
me.items = [{
xtype: "form",
width: 700,
autoHeight: true,
fieldDefaults: {
labelAlign: "right",
labelStyle: "font-weight:bold;"
},
border: false
}]
//操作按钮直接加载window上
me.buttons = ["->", {
text: "新增",
cls: "green-btn",
iconCls: baseConfig.appicon.add,
handler: function () {
var form = this.down("form");
if (form.isValid()) {
form.submit({
url: "sys/user/update",
method: "POST",
waitTitle: "提示",
waitMsg: "正在提交数据,请稍后 ……",
success: function (form, action) {//添加成功后提示消息,并且刷新用户列表数据
me.close();
DealAjaxResponse(action.response);
Ext.data.StoreManager.lookup("UserStore").load();
},
failure: function (form, action) {
DealAjaxResponse(action.response);
}
});
} else {
toast({
msg: "表单填写错误,请确认"
})
}
},
scope: this
}, "-", {
text: "放弃",
cls: "red-btn",
iconCls: baseConfig.appicon.undo,
handler: function () {
me.close();
},
scope: this
}]
me.callParent(arguments);
},
loadView: function (config) {
var formCmp = this.getComponent(0);
formCmp.add([{
columnWidth: 1,
layout: "form",
items: [{
xtype: "hidden",//这里放一个隐藏控件,因为是修改记录,所以必须提交ID
name: "id"
}, {
xtype: "textfield",
fieldLabel: baseConfig.model.user.username,
name: "username",
maxLength: 250,
maxLengthText: "请输入{0}个字以内",
emptyText: "登录用的用户名",
allowBlank: false,
flex: 1
},
{
xtype: "textfield",
fieldLabel: baseConfig.model.user.real_name,
name: "real_name",
maxLength: 10,
maxLengthText: "请输入{0}个字以内",
emptyText: "真实姓名",
allowBlank: false,
flex: 1
}
]
}]);
}
});
我们希望在双击用户列表中的某一条记录(某个用户)的时候,弹出用户修改对话框,所以,修改用户列表页面代码,添加列表行双击事件的监听,如下:
</>复制代码
。。。。。。
me.listeners = {
"itemdblclick": function (table, record, html, row, event, opt) {
if (record) {
var id = record.get("id");
var view = Ext.create("luter.view.sys.user.UserEdit", {title: "编辑数据", animateTarget: this});
view.loadView();
//为了保证数据完整性,拿到这条数据的ID后,需要从后台获取当前这条数据,然后再修改
//对于后台而言,最好对数据设置@version功能,确保数据一致性。
loadFormDataFromDb(view, "app/testdata/user.json");
} else {
showFailMesg({
msg: "加载信息失败,请确认。"
})
}
}
}
。。。。。。
添加记录删除操作
在用户列表中,设置action列,实现删除操作,如下:
</>复制代码
.......
me.columns = [{
xtype: "rownumberer",
text: "序号",
width: 60
}, {
header: "操作",
xtype: "actioncolumn",
width: 60,
sortable: false,
items: [{
text: "删除",
iconCls: "icon-delete",
tooltip: "删除这条记录",
handler: function (grid, rowIndex, colIndex) {
var record = grid.getStore().getAt(rowIndex);
if (!record) {
toast({
msg: "请选中一条要删除的记录"
})
} else {
showConfirmMesg({
message: "确定删除这条记录?",
fn: function (btn) {
if (btn === "yes") {
showToastMessage("啥意思?");//测试一下而已,实际情况是执行ajax删除,如下。
// Ext.Ajax.request({
// url: "sys/user/delete",
// method: "POST",
// params: {
// id: record.get("id")
// },
// success: function (response, options) {
// DealAjaxResponse(response);
// Ext.data.StoreManager.lookup("UserStore").load();
// },
// failure: function (response, options) {
// DealAjaxResponse(response);
// }
// });
} else {
Ext.toast({
title:"看...",
width:200,
html: "不删了....."
});
return false;
}
}
})
}
}
}]
}, {
header: baseConfig.model.user.id,
dataIndex: "id",
hidden: false,
flex: 1
},
{
header: baseConfig.model.user.username,
dataIndex: "username",
flex: 1
},
{
header: baseConfig.model.user.real_name,
dataIndex: "real_name",
flex: 1
}
]
.......
extjs样式覆盖app/resource/css/admin.css
主要覆盖了左侧导航菜单treelist和中间tabpanel的部分风格样式,
记得在app.html中extjs样式之后引入覆盖样式
</>复制代码
.x-treelist-navigation {
background-color: #32404e;
background-position: 44px 0%;
padding: 0 0 0 0
}
.x-big .x-treelist-navigation {
background-position: 0%
}
.x-treelist-navigation .x-treelist-toolstrip {
background-color: #32404e
}
.x-treelist-navigation .x-treelist-item-selected.x-treelist-item-tool {
background-color: #475360
}
.x-treelist-navigation .x-treelist-item-selected.x-treelist-item-tool:after {
height: 50px;
position: absolute;
top: 0;
left: 0;
content: " ";
width: 5px;
background-color: #35baf6
}
.x-treelist-navigation .x-treelist-item-selected > .x-treelist-row {
background-color: #475360
}
.x-treelist-navigation .x-treelist-item-tool {
padding-left: 10px;
padding-right: 10px
}
.x-treelist-navigation .x-treelist-item-tool-floated:after {
height: 50px;
position: absolute;
top: 0;
left: 0;
content: " ";
width: 5px;
background-color: #35baf6
}
.x-treelist-navigation .x-treelist-item-icon:before, .x-treelist-navigation .x-treelist-item-tool:before, .x-treelist-navigation .x-treelist-item-expander {
line-height: 50px
}
.x-treelist-navigation .x-treelist-item-icon, .x-treelist-navigation .x-treelist-item-tool, .x-treelist-navigation .x-treelist-item-expander {
text-align: center;
background-repeat: no-repeat;
background-position: 0 center
}
.x-treelist-navigation .x-treelist-item-icon, .x-treelist-navigation .x-treelist-item-tool {
color: #adb3b8;
font-size: 18px;
width: 44px
}
.x-treelist-navigation .x-treelist-item-tool {
width: 50px
}
.x-treelist-navigation .x-treelist-item-expander {
color: #fff;
font-size: 16px;
width: 24px
}
.x-treelist-navigation .x-treelist-item-text {
color: #adb3b8;
margin-left: 50px;
margin-right: 24px;
font-size: 14px;
font-weight: 900;
line-height: 50px
}
.x-treelist-navigation .x-treelist-row {
padding-left: 10px;
padding-right: 10px
}
.x-treelist-navigation .x-treelist-row-over:before, .x-treelist-navigation .x-treelist-item-selected > .x-treelist-row:before {
content: " ";
position: absolute;
display: block;
left: 0;
top: 0;
width: 5px;
height: 100%
}
.x-treelist-navigation .x-treelist-row-over:before {
background-color: transparent
}
.x-treelist-navigation .x-treelist-item-selected > .x-treelist-row-over:before {
background-color: #57c6f8
}
.x-treelist-navigation .x-treelist-item-selected > .x-treelist-row:before {
background-color: #35baf6
}
.x-treelist-navigation .x-treelist-item-floated .x-treelist-container {
width: auto
}
.x-treelist-navigation .x-treelist-item-floated > .x-treelist-row {
background-color: #32404e
}
.x-treelist-navigation .x-treelist-item-floated > .x-treelist-container {
margin-left: -44px
}
.x-big .x-treelist-navigation .x-treelist-item-floated > .x-treelist-container {
margin-left: 0
}
.x-treelist-navigation .x-treelist-item-floated > * > * > .x-treelist-item-text {
margin-left: 0
}
.x-treelist-navigation .x-treelist-item-floated > * .x-treelist-row {
padding-left: 0
}
.x-treelist-navigation .x-treelist-item-floated .x-treelist-row:before {
width: 0
}
.x-treelist-navigation .x-treelist-item-floated > .x-treelist-row-over {
background-color: #32404e
}
.x-treelist-navigation .x-treelist-item-floated > .x-treelist-row-over > * > .x-treelist-item-text {
color: #adb3b8
}
.x-treelist-navigation .x-treelist-item-expanded {
background-color: #2c3845
}
.x-treelist-navigation.x-treelist-highlight-path .x-treelist-item-over > * > .x-treelist-item-icon {
color: #fff
}
.x-treelist-navigation.x-treelist-highlight-path .x-treelist-item-over > * > .x-treelist-item-text {
color: #d6d9dc
}
.x-treelist-navigation.x-treelist-highlight-path .x-treelist-item-over > * > .x-treelist-item-expander {
color: #fff
}
.x-treelist-navigation .x-treelist-row-over {
background-color: #3c4a57
}
.x-treelist-navigation .x-treelist-row-over > * > .x-treelist-item-icon {
color: #fff
}
.x-treelist-navigation .x-treelist-row-over > * > .x-treelist-item-text {
color: #d6d9dc
}
.x-treelist-navigation .x-treelist-row-over > * > .x-treelist-item-expander {
color: #fff
}
.x-treelist-navigation .x-treelist-expander-first .x-treelist-item-icon {
left: 24px
}
.x-treelist-navigation .x-treelist-expander-first .x-treelist-item-text {
margin-left: 74px;
margin-right: 0
}
.x-treelist-navigation .x-treelist-expander-first .x-treelist-item-hide-icon > * > * > .x-treelist-item-text {
margin-left: 30px
}
.x-treelist-navigation .x-treelist-item-hide-icon > * > * > .x-treelist-item-text {
margin-left: 6px
}
.x-tab-bar-default{
height: 40px;
/*background-color: #0e2349;*/
}
.x-tab-default-top {
-webkit-border-radius: 0;
-moz-border-radius: 0;
-ms-border-radius: 0;
border-radius: 0;
padding: 8px 10px 7px 10px;
border-width: 0;
border-style: solid;
background-color: transparent
}
.x-tab-bar-default-top > .x-tab-bar-body-default{
padding:0
}
.x-nbr .x-tab-default-top {
padding: 0 !important;
border-width: 0 !important;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
-ms-border-radius: 0px;
border-radius: 0px;
background-color: transparent !important;
box-shadow: none !important
}
.x-tab-default {
border-color: transparent;
cursor: pointer
}
.x-tab-default-top {
margin: 0 4px 0 0
}
.x-tab-default-top.x-tab-rotate-left {
margin: 0 0 0 4px
}
.x-tab-default-top.x-tab-focus {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none
}
.x-tab-default-top.x-tab-focus.x-tab-over {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none
}
.x-tab-default-top.x-tab-focus.x-tab-active {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
background-color: #1d9ce5;
}
.x-tab-button-default {
padding-top: 5px;
height: 20px
}
.x-tab-inner-default {
font: 500 13px/20px "Open Sans", "Helvetica Neue", helvetica, arial, verdana, sans-serif;
/*color: #f0f0f0;*/
max-width: 100%
}
.x-tab-bar-plain .x-tab-inner-default {
color: #606060
}
.x-tab-icon-right>.x-tab-inner-default,
.x-tab-icon-left>.x-tab-inner-default {
max-width: calc(100% - 20px)
}
.x-tab-icon-el-default {
min-height: 20px;
background-position: center center;
font-size: 20px;
line-height: 20px;
color: #f0f0f0
}
.x-tab-icon-left>.x-tab-icon-el-default,
.x-tab-icon-right>.x-tab-icon-el-default {
width: 20px
}
.x-tab-icon-top>.x-tab-icon-el-default,
.x-tab-icon-bottom>.x-tab-icon-el-default {
min-width: 20px
}
.x-tab-bar-plain .x-tab-icon-el-default {
color: #606060
}
.x-tab-icon-el-default.x-tab-glyph {
opacity: 0.7
}
.x-tab-text.x-tab-icon-left>.x-tab-icon-el-default {
margin-right: 6px
}
.x-tab-text.x-tab-icon-right>.x-tab-icon-el-default {
margin-left: 6px
}
.x-tab-text.x-tab-icon-top>.x-tab-icon-el-default {
margin-bottom: 6px
}
.x-tab-text.x-tab-icon-bottom>.x-tab-icon-el-default {
margin-top: 6px
}
.x-tab-focus.x-tab-default {
border-color: transparent;
background-color: transparent;
outline: 1px solid #35baf6;
outline-offset: -3px
}
.x-ie .x-tab-focus.x-tab-default,
.x-ie10p .x-tab-focus.x-tab-default,
.x-edge .x-tab-focus.x-tab-default {
outline: none
}
.x-ie .x-tab-focus.x-tab-default:after,
.x-ie10p .x-tab-focus.x-tab-default:after,
.x-edge .x-tab-focus.x-tab-default:after {
position: absolute;
content: " ";
top: 2px;
right: 2px;
bottom: 2px;
left: 2px;
border: 1px solid #35baf6;
pointer-events: none
}
.x-tab-bar-plain .x-tab-focus.x-tab-default .x-tab-inner-default {
color: #606060
}
.x-tab-bar-plain .x-tab-focus.x-tab-default .x-tab-icon-el {
color: #606060
}
.x-tab-over.x-tab-default {
border-color: #000;
background-image: none;
background-color: rgba(0, 0, 0, 0.08)
}
.x-ie8 .x-tab-over.x-tab-default {
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#14000000, endColorstr=#14000000)";
zoom: 1
}
.x-ie8 .x-tab-over.x-tab-default.x-tab-rotate-left {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"
}
.x-ie8 .x-tab-over.x-tab-default.x-tab-rotate-right {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"
}
.x-tab-bar-plain .x-tab-over.x-tab-default .x-tab-inner-default {
color: #606060
}
.x-tab-bar-plain .x-tab-over.x-tab-default .x-tab-icon-el {
color: #606060
}
.x-tab-focus.x-tab-over.x-tab-default {
border-color: #000;
background-image: none;
background-color: rgba(0, 0, 0, 0.08)
}
.x-ie8 .x-tab-focus.x-tab-over.x-tab-default {
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#14000000, endColorstr=#14000000)";
zoom: 1
}
.x-ie8 .x-tab-focus.x-tab-over.x-tab-default.x-tab-rotate-left {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"
}
.x-ie8 .x-tab-focus.x-tab-over.x-tab-default.x-tab-rotate-right {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"
}
.x-tab-bar-plain .x-tab-focus.x-tab-over.x-tab-default .x-tab-inner-default {
color: #606060
}
.x-tab-bar-plain .x-tab-focus.x-tab-over.x-tab-default .x-tab-icon-el {
color: #606060
}
.x-tab.x-tab-active.x-tab-default {
border-color: #fff;
background-color: #fff
}
.x-tab.x-tab-active.x-tab-default .x-tab-inner-default {
color: #105bf3
}
.x-tab-bar-plain .x-tab.x-tab-active.x-tab-default .x-tab-inner-default {
color: #404040
}
.x-tab.x-tab-active.x-tab-default .x-tab-icon-el {
color: #105bf3
}
.x-ie8 .x-tab.x-tab-active.x-tab-default .x-tab-icon-el {
color: #6ab5d6
}
.x-tab-bar-plain .x-tab.x-tab-active.x-tab-default .x-tab-icon-el {
color: #404040
}
.x-tab-focus.x-tab-active.x-tab-default {
border-color: #fff;
background-color: #fff
}
.x-tab-bar-plain .x-tab-focus.x-tab-active.x-tab-default .x-tab-inner-default {
color: #404040
}
.x-tab-bar-plain .x-tab-focus.x-tab-active.x-tab-default .x-tab-icon-el {
color: #404040
}
.x-tab.x-tab-disabled.x-tab-default {
border-color: transparent;
background-color: transparent;
cursor: default
}
.x-tab.x-tab-disabled.x-tab-default .x-tab-inner-default {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)";
opacity: 0.3
}
.x-tab-bar-plain .x-tab.x-tab-disabled.x-tab-default .x-tab-inner-default {
color: #606060
}
.x-tab.x-tab-disabled.x-tab-default .x-tab-icon-el-default {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
opacity: 0.5
}
.x-tab.x-tab-disabled.x-tab-default .x-tab-icon-el {
color: #f0f0f0;
opacity: 0.3;
filter: none
}
.x-tab-bar-plain .x-tab.x-tab-disabled.x-tab-default .x-tab-icon-el {
color: #606060
}
.x-nbr .x-tab-default {
background-image: none
}
.x-tab-default .x-tab-close-btn:before {
content: "f00d"
}
.x-tab-default .x-tab-close-btn {
top: 0;
right: 0;
width: 12px;
height: 12px;
font: 12px/1 FontAwesome;
color: red
}
.x-tab-default.x-tab-active .x-tab-close-btn {
color: red
}
.x-tab-default .x-tab-close-btn-over {
background-position: -12px 0;
color: red
}
至此,应该能看到基本的界面的样子了:)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/92693.html
摘要:结构实践三完善基本页面一般经典的后台管理系统,都是左侧菜单右侧结构布局。不免俗,咱也这么实现定义左侧导航菜单新建采用的组件构建一个导航菜单为了显示图标,引入字体图标,在引入引入定义导航菜单数据功能菜单展开节点。 extjs-mvc结构实践(三):完善基本页面2 一般经典的后台管理系统,都是左侧菜单右侧tabs结构布局。不免俗,咱也这么实现! 定义左侧导航菜单 新建:app/luter/...
摘要:值得一提的是扩展包不免费用于商业用途,作者用一种人类友好的方式说你使用这个扩展包就是应该去挣钱的,而不是免费的去工作这个扩展包收费美元。除了这些,还有五个没有全面的审查的扩展包。最后,还有三个优质的包选择于。 showImg(https://segmentfault.com/img/remote/1460000012312105?w=2200&h=1125); 开发者们都是懒惰的,不,...
摘要:值得一提的是扩展包不免费用于商业用途,作者用一种人类友好的方式说你使用这个扩展包就是应该去挣钱的,而不是免费的去工作这个扩展包收费美元。除了这些,还有五个没有全面的审查的扩展包。最后,还有三个优质的包选择于。 showImg(https://segmentfault.com/img/remote/1460000012312105?w=2200&h=1125); 开发者们都是懒惰的,不,...
阅读 1316·2021-11-22 12:05
阅读 1427·2021-09-29 09:35
阅读 719·2019-08-30 15:55
阅读 3210·2019-08-30 14:12
阅读 1041·2019-08-30 14:11
阅读 2953·2019-08-30 13:10
阅读 2497·2019-08-29 16:33
阅读 3404·2019-08-29 11:02