extjs4mvc增删改查_extjs-mvc结构实践(五):实现用户管理的增删改查

经过前面几篇文章的介绍,一个基本的MVC结构应该是具备了。而且上一篇文章中,也已经实现了一个基本的用户管理列表页面。接着上一篇,完善用户管理,实现增删改。为了用户体验,增加和修改用户信息的表单,都放在弹窗中进行。避免跳转页面。

定义用户增加窗口:app/luter/view/sys/user/UserAdd.js

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

}

至此,应该能看到基本的界面的样子了:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值