이번에는 지난 포스팅에 이어서 그리드 페이징 처리 및버튼 handler를 click 리스너 이벤트로 변경을 하여컨트롤러에 담아보도록 해보겠습니다.이전 강의에 이어서 진행하게 되므로이전 포스팅을 우선 진행 하신다음이어서 해당 포스팅을 참조하시면 되겠습니다.2014/12/29 - [웹개발강좌/ExtJS] - ExtJS 강좌 - ExtJS5 MVC 구조를 이용한..
오랫만에 ExtJS 강좌 포스팅을 등록해보도록 하겠습니다.지난 시간까지 ExtJS MVC 구조에 대하여 잡아보았습니다.2014/11/26 - [웹개발강좌/ExtJS] - ExtJS 강좌 - ExtJS5 MVC 구조 잡아보기(View+Controller 연동)2014/11/26 - [웹개발강좌/ExtJS] - ExtJS 강좌 - ExtJS5 MVC 구조 잡아..
이전 Spring3 +ExtJS파일업로드 관련하여 포스팅을 한 적이 있습니다.2014/10/28 - [웹개발강좌/ExtJS] - ExtJS 강좌 - 파일필드를 이용하여 파일업로드하기(html5를 이용한 다중파일 포함)"Deoki"님께서 질문주신결과Spring의 @ResponseBody + Jackson JSON 라이브러리를 이용하여JSON 파싱한 결과크롬에..
이번에는 지난 포스팅에 이어서 그리드 페이징 처리 및
버튼 handler를 click 리스너 이벤트로 변경을 하여
컨트롤러에 담아보도록 해보겠습니다.
이전 강의에 이어서 진행하게 되므로
이전 포스팅을 우선 진행 하신다음
이어서 해당 포스팅을 참조하시면 되겠습니다.
2014/12/29 - [웹개발강좌/ExtJS] - ExtJS 강좌 - ExtJS5 MVC 구조를 이용한 간단 그리드 CRUD 알아보기(1)
그럼 기존 코드에서 약간 코드들을 수정해보면서 하단처럼 그리드 페이징처리와
버튼 클릭을 handler 가 아닌 컨트롤러에 클릭이벤트로 적용을 해보도로 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | Ext.define( 'mvc_study.view.grid.CustomGrid' , { extend: 'Ext.grid.Panel' , //xtype에 들어가는 컴포넌트 명칭이다. //widget. << 이부분을 제외한 나머지명칭을 xtype에 선언 해주면 됨 alias : 'widget.customGrid' , title : '그리드 CRUD' , //로우에디터를 사용하기 위한 플러그인 설정 plugins: [Ext.create( 'Ext.grid.plugin.RowEditing' , { clicksToMoveEditor: 1, autoCancel: false })], columns : [ //idx 컬럼은 수정이불가하므로 editor 속성을 제거 //그외 title,name에만 editor 속성 허용 { text : '번호' , flex : 1, dataIndex : 'idx' },{ text : '제목' , flex : 1, dataIndex : 'title' , editor: { xtype: 'textfield' } },{ text : '이름' , flex : 1, dataIndex : 'name' , editor: { xtype: 'textfield' } }], store : 'GridStore' , dockedItems : [ { //페이징 툴바 xtype : 'pagingtoolbar' , //그리드로부터 툴바생성위치 dock : 'bottom' , //store store : 'GridStore' , //정보 보여주기 false일 경우 하단속성은 필요없음 displayInfo : true , //보여주기 메시지(데이터 존재할때) displayMsg: '현재데이터 : {0} - {1} / 총데이터 : {2}' , //데이터 존재하지 않을경우 emptyMsg: "데이터없음" } ], fbar : [{ xtype : 'button' , text : '추가' , id : 'addBtn' },{ xtype : 'button' , text : '삭제' , id : 'removeBtn' },{ xtype : 'button' , text : '적용' , id : 'applyBtn' }], initComponent: function () { this .callParent(); } }); |
위에 코드에 설명을 추가하자면 페이징 처리를 위하여
"pagingtoolbar" 컴포넌트를 dockedItems 속성내에 정의를 하였습니다.
MVC를 사용안하고 페이징 툴바에 관한 포스팅은 하단을 참고해주세요
2014/11/03 - [웹개발강좌/ExtJS] - ExtJS 강좌 - 그리드패널에 페이징툴바를 적용하여 페이징 목록 출력하기
autoLoad : true, 코드 다음에 하단 코드를 추가해줍니다.
1 | pageSize: 3, |
pageSize속성은 한페이지당 출력할 데이터 갯수를 의미합니다.
이어서 GridStore의 reader 자식 속성에 다음 코드를 추가합니다.
1 | ,totalProperty: 'totalCount' |
reader의 자식속성에 존재하는 rootProperty와 동일하게
totalProperty에 정의된 속성값 역시 서버 페이지에서 응답받는 json의 key값과 동일하게 맞춰줍니다.
※ totalProperty는 원격서버로부터 페이징시 필요한 속성값이므로 기억해두도록 합니다.
★★★★★★
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | Ext.define( 'mvc_study.controller.MvcController' , { extend: 'Ext.app.Controller' , stores : [ 'GridStore' ], views: [ 'grid.CustomGrid' ], init: function () { this .control({ '#addBtn' : { click : this .addBtn }, '#removeBtn' : { click : this .removeBtn }, '#applyBtn' : { click : this .applyBtn } }); }, addBtn : function (btn){ //GridModel var rec = Ext.create( 'mvc_study.model.GridModel' ,{ title: '' , name : '' }); //로우 추가 btn.up( "grid" ).getStore().insert(0,rec); //에디트 포커스 btn.up( "grid" ).plugins[0].startEdit(0, 0); }, removeBtn : function (btn){ //선택된 로우 삭제 btn.up( "grid" ).getStore().remove(btn.up( "grid" ).getSelectionModel().getSelection()); }, applyBtn : function (btn){ //각 row 마다 싱크를 맞춰주면서 btn.up( "grid" ).getStore().sync({ //성공시 success: function ( response ) { //그리드 select btn.up( "grid" ).getStore().load(); } }); } }); |
MvcController에서 변경 및 추가된 점이 있다면
init의 this.controller부분에 CustomGrid에 선언한
버튼아이디셀렉터 : {
리스너이벤트명칭1(ex:click) : 함수명
리스터이벤트명칭2(ex:render) : 함수명
}
위처럼 선언이 되어있는데 이 구조 또한 기억해두도록 합니다.
그리고 함수명을 선언한 명칭으로 컨트롤러 영역에 선언한
함수명 : function(){
// 기능정의
}
처럼 지정을 해놓았습니다.
기능정의 부분은 이전에 선언한 CustomGrid 커스텀 컴포넌트의
버튼 handler 영역의 코드를 그대로 가져다 사용하였습니다.
간단하게 설명을 드려보자면
id가 "addBtn" 인 컴포넌트의 클릭이벤트 발생시 addBtn 함수 호출
id가 "removeBtn" 인 컴포넌트의 클릭이벤트 발생시 removeBtn 함수 호출
id가 "applyBtn" 인 컴포넌트의 클릭이벤트 발생시 applyBtn 함수 호출
형태로 동작이 되는 것입니다.
스크립트 코드수정이 이로써 마무으리!!가 되었습니다.
이어서 서버페이지 부분에 대한 코드를 재작성 해보도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | @RequestMapping ( "/listData" ) public @ResponseBody Map<String , Object> listData(HttpServletRequest request) throws SQLException { Map<String, Object> parameterMap = new HashMap<String, Object>(); Map<String, Object> resultMap = new HashMap<String, Object>(); //게시물 목록 수 조회 int totalCount = dao.totalCount(); //----클라이언트 페이지로부터 넘어온 parameter값들---- int start = Integer.parseInt(request.getParameter( "start" )); int end = Integer.parseInt(request.getParameter( "limit" )); //----클라이언트 페이지로부터 넘어온 parameter값들---- parameterMap.put( "start" , start); parameterMap.put( "end" , end); //게시물 목록 조회 ArrayList<Map<String, Object>> list = dao.listData(parameterMap); resultMap.put( "success" , true ); resultMap.put( "items" , list); //그리드 페이징을 위한 필수 response json key 값 resultMap.put( "totalCount" , totalCount); return resultMap; } |
DB호출하는 쿼리 페이지는 다음과 같이 변경 및 추가하였습니다.
1 2 3 4 5 6 7 8 9 10 11 | < select id = "totalCount" resultType = "Integer" > SELECT COUNT(*) FROM grid </ select > < select id = "listData" parameterType = "java.util.Map" resultType = "java.util.Map" > SELECT idx,title, name FROM grid ORDER BY idx DESC LIMIT #{start}, #{end} </ select > |
INSERT/UPDATE/DELETE 로직은 변경사항이 없으므로 기능은 정의하지 않았습니다.
그럼 실행결과를 보도록 해보겠습니다.
정상적으로 컨트롤러 영역에 리스너 이벤트가 정상적으로 동작되는 것을 확인 하였습니다.
또한 그리드 페이징 처리 역시 잘 나오네요 ^^
by 개발로짜
ExtJS 강좌 - ExtJS5 MVC 구조를 이용한 간단 그리드 CRUD 알아보기(1) (13) | 2014.12.29 |
---|---|
Spring @ResposeBody를 이용하여 JSON Response 할때 IE에서 다운로드현상 해결법 (4) | 2014.12.07 |
ExtJS 강좌 - ExtJS5 MVC 구조 잡아보기(View/Controller + Model+Store 추가) (0) | 2014.11.26 |
ExtJS 강좌 - ExtJS5 MVC 구조 잡아보기(View+Controller 연동) (2) | 2014.11.26 |
ExtJS 강좌 - Sencha CMD로 ExtJS 구조 생성하여 연동테스트 해보기 (1) | 2014.11.24 |
오랫만에 ExtJS 강좌 포스팅을 등록해보도록 하겠습니다.
지난 시간까지 ExtJS MVC 구조에 대하여 잡아보았습니다.
2014/11/26 - [웹개발강좌/ExtJS] - ExtJS 강좌 - ExtJS5 MVC 구조 잡아보기(View+Controller 연동)
2014/11/26 - [웹개발강좌/ExtJS] - ExtJS 강좌 - ExtJS5 MVC 구조 잡아보기(View/Controller + Model+Store 추가)
이번장에는 기존 연동되어있는 MVC 구조를 이용하여 DB와 연동하여
C : DB INSERT
R : DB SELECT
U : DB UPDATE
D : DB DELETE
작업을 수행해보도록 하겠습니다.
DB 연동에 대해서는 본인이 작업하는 환경에 맞추어 미리 연동을 해놓으시기 바라겠습니다.
저같은경우는 JSP 기반 SPRING Framework 를 이용하여 DB 연동을 하였습니다
DBMS는 MySQL을 이용하여 다음과 같은 구조의 테이블을 생성하였습니다.
1 2 3 4 5 6 | CREATE TABLE `grid` ( `idx` int (11) NOT NULL AUTO_INCREMENT, `title` varchar (100) DEFAULT NULL , ` name ` varchar (100) DEFAULT NULL , PRIMARY KEY (`idx`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 |
Oracle 혹은 MSSQL등 MySQL이 아닌 다른 DBMS에는
컬럼타입과 컬럼명만 맞추기만 하여 테이블 생성하시면 되겠습니다.
이어서 임의로 가상의 데이터 몇가지를 insert 해보도록 하겠습니다.
1 2 3 4 5 6 | INSERT INTO grid(title, NAME ) VALUES ( '제목1' , '이름1' ); INSERT INTO grid(title, NAME ) VALUES ( '제목2' , '이름2' ); INSERT INTO grid(title, NAME ) VALUES ( '제목3' , '이름3' ); |
이어서 각 MVC 폴더구조는 다음과 같습니다.
그럼 각 MVC 파일들에 대한 코드를 간단하게 작성 및 설명을 해보도록 하겠습니다.
1 2 3 4 5 6 7 | <!-- ExtJS 연동 관련 INCLUDE 파일들 --> < link rel = "stylesheet" type = "text/css" href = "/resource/extjs/ext-theme-crisp-touch/build/resources/ext-theme-crisp-touch-all.css" /> < script type = "text/javascript" src = "/resource/extjs/ext-all.js" ></ script > < script type = "text/javascript" src = "/resource/extjs/ext-theme-crisp-touch/build/ext-theme-crisp-touch.js" ></ script > < script type = "text/javascript" src = "/resource/extjs/ext-theme-crisp-touch/build/ext-theme-crisp-touch.js" ></ script > <!-- ExtJS MVC 연동 파일 --> < script type = "text/javascript" src = "/resource/mvc.js" ></ script > |
별도의 HTML코드는 필요없습니다.
<head></head> 태그 사이에 include 해주도록 합니다.
1 2 3 4 5 6 7 8 | Ext.application({ name: 'mvc_study' , appFolder : '/resource/mvc_study' , controllers: [ 'MvcController' ], autoCreateViewport: true }); |
MVC 선언 시
appFolder : mvc 구조를 잡기위한 최상단 루트폴더지정 없을시 "/app" 이 default
controllers : 컨트롤러 파일 설정을 위한 설정
1 2 3 4 5 6 7 8 9 10 11 | Ext.define( 'mvc_study.view.Viewport' , { extend: 'Ext.container.Viewport' , layout : 'border' , items : [{ region : 'center' , xtype : 'customGrid' }], initComponent: function () { this .callParent(); } }); |
MVC에서 최초 LOAD의 시작파일
※ 기존 Ext.create와 같은 구조입니다.
다른점이 있다면, renderTo를 별도로 해주실 필요가 없으며
Viewport 클래스를 상속받는 것 외에는 없습니다.
구조는 이전에 했던 방식과 동일합니다.
이어서 xtype이 customGrid인 컴포넌트를 지정을 하였는데
컴포넌트는 기본으로 제공하는 컴포넌트가 아닌 사용자지정 컴포넌트입니다.
그럼 customGrid에 대하여 정의를 해보도록 합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | Ext.define( 'mvc_study.view.grid.CustomGrid' , { extend: 'Ext.grid.Panel' , //xtype에 들어가는 컴포넌트 명칭이다. //widget. << 이부분을 제외한 나머지명칭을 xtype에 선언 해주면 됨 alias : 'widget.customGrid' , title : '그리드 CRUD' , //로우에디터를 사용하기 위한 플러그인 설정 plugins: [Ext.create( 'Ext.grid.plugin.RowEditing' , { clicksToMoveEditor: 1, autoCancel: false })], columns : [ //idx 컬럼은 수정이불가하므로 editor 속성을 제거 //그외 title,name에만 editor 속성 허용 { text : '번호' , flex : 1, dataIndex : 'idx' },{ text : '제목' , flex : 1, dataIndex : 'title' , editor: { xtype: 'textfield' } },{ text : '이름' , flex : 1, dataIndex : 'name' , editor: { xtype: 'textfield' } }], store : 'GridStore' , fbar : [{ xtype : 'button' , text : '추가' , handler : function (btn){ //GridModel var rec = Ext.create( 'mvc_study.model.GridModel' ,{ title: '' , name : '' }); //로우 추가 btn.up( "grid" ).getStore().insert(0,rec); //에디트 포커스 btn.up( "grid" ).plugins[0].startEdit(0, 0); } },{ xtype : 'button' , text : '삭제' , handler : function (btn){ //선택된 로우 삭제 btn.up( "grid" ).getStore().remove(btn.up( "grid" ).getSelectionModel().getSelection()); } },{ xtype : 'button' , text : '적용' , handler : function (btn){ //각 row 마다 싱크를 맞춰주면서 btn.up( "grid" ).getStore().sync({ //성공시 success: function ( response ) { //그리드 select btn.up( "grid" ).getStore().load(); } }); } }], initComponent: function () { this .callParent(); } }); |
이어서 customGrid의 config속성중
store에 선언되어있는
GridStore에 대하여 정의를 해보도록 합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | Ext.define( 'mvc_study.store.GridStore' , { extend: 'Ext.data.Store' , model: 'mvc_study.model.GridModel' , //페이지 로드시 자동으로 READ 조회 autoLoad : true , proxy: { type: 'ajax' , api: { //등록페이지 create : '/insertData' , //조회페이지 read: '/listData' , //수정페이지 update : '/updateData' , //삭제페이지 destroy : '/deleteData' }, //select 옵션 reader: { type: 'json' , successProperty: 'success' , //응답받는 json object의 최상단 key값(SELECT 구문) //{ // data : 'value' //} rootProperty: 'items' }, //create,update,delete 옵션 writer: { type: 'json' , //그리드 row의 모든값 전송 writeAllFields: true , //필수속성값 encode : true , //문자열로 넘어가는 서버 parameter값 json object의 최상단 key값(INSERT/UPDATE/DELETE 구문) //java 기준 : request.getParameter("data"); rootProperty: 'data' } } }); |
store는 기존포스팅을 따라오셨던 분들이시라면
크게 변한 부분은 없을 것입니다.
변경된 점이 있다면
proxy에 api부분에 (create/read/update/destroy) 속성과
writer 속성이 추가된것이 전부입니다.
주석으로 설명 대체를 하도록 하겠습니다 ^^ㅋㅋ
다음은 store에 설정한
model 속성에 정의된 GridModel에 대한 코드를 작성해보도록 합니다.
1 2 3 4 | Ext.define( 'mvc_study.model.GridModel' , { extend: 'Ext.data.Model' , fields: [ 'idx' , 'title' , 'name' ] }); |
모델을 생략하고 fields 속성을 데이터스토어에 정의를 해주셔도 무관하나
MVC에 관련된 내용이므로 MODEL에 fields 속성을 정의하였습니다.
화면에 대한 정의는 완료되었으나
뷰를 화면에 표출을 시키기 위하여 컨트롤러 파일을 다음과 같이 작성합니다.
1 2 3 4 5 6 7 8 | Ext.define( 'mvc_study.controller.MvcController' , { extend: 'Ext.app.Controller' , stores : [ 'GridStore' ], views: [ 'grid.CustomGrid' ], init: function () { this .control(); } }); |
실질적으로 그리드 툴바들에 대한 버튼 컨트롤을 위하여
각 refs 라는 속성내에 버튼을 정의후 클릭이벤트에 대하여 기능을 구현하여야 하겠지만
이부분에 대해서는 다음 장에 그리드 페이징 및 컨트롤러 사용에 대하여 설명을 진행하겠습니다.
마지막으로 데이터 스토어에서 정의된 각각의 데이터통신을 하는 URL에 대한 샘플 코드를 작성하도록 하겠습니다.
서버페이지는 Spring MVC + Mybatis 를 이용하여 출력하며
JSON 파싱부분은 Jackson JSON을 이용하였습니다.
PHP 및 ASP 를 사용하시는 분들은 별도로 코드에 대한 설명을 파악 후
JSON REQUEST/RESPONSE 구조만 맞춰주시면 동일한 결과를 얻으실 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | /** * response json 결과값은 다음처럼 나와야 합니다. * {"items":[ * {"title":"제목3","idx":24,"name":"이름3"}, * {"title":"제목2","idx":23,"name":"이름2"}, * {"title":"제목1","idx":22,"name":"이름1"}], * "success":true} */ //list logic @RequestMapping ( "/listData" ) public @ResponseBody Map<String , Object> listData(HttpServletRequest request) throws SQLException { Map<String, Object> map = new HashMap<String, Object>(); //DB 목록 조회 ArrayList<Map<String, Object>> list = dao.listData(); //데이터스토어에 reader -> successPropery값과 맞춰줌 (true/false) map.put( "success" , true ); //데이터스토어에 reader -> rootProperty값과 맞춰줌 //DB목록값에 대한 JSON KEY값은 items가 되어야 한다 map.put( "items" , list); return map; } /** * CREATE / UPDATE / DELETE 에 대한 JSON REQUEST 및 RESPONSE에 대한 구조는 동일 * 다른점은 DB통신하는 부분만 변경해주면 됨 * REQUEST 구조 * jsp = request.getParameter("data"); * php = $_REQUEST['data'] * asp = <%=request("data") %> * 위와같이 하면 JSON문자열 데이터로 넘어옵니다. * 넘어온 문자열을 각 언어에 맞게끔 string to object로 변환하는 방식을 이용합니다. * 제가 사용한 Jackson JSON라이브러리는 단일 object, 배열 object별로 구분을 해주어야 하므로 * 넘어온 json 문자열에 맨 앞 표시에 따라 구분을 하였습니다. * * RESPONSE 구조 * DB가 정상적으로 등록/수정/삭제 되었다 가정하고 * {success : true} * 라는 JSON OBJECT를 RESPONSE 해줍니다. */ //insert logic @RequestMapping ( "/insertData" ) public @ResponseBody Map<String , Object> insertData(HttpServletRequest request) throws JsonParseException, JsonMappingException, IOException, SQLException { Map<String, Object> hmap = new HashMap<String, Object>(); hmap.put( "success" , true ); String data = request.getParameter( "data" ); ObjectMapper mapper = new ObjectMapper(); if (data.substring( 0 , 1 ).equals( "{" )) { Map<String, Object> map = mapper.readValue(data, Map. class ); dao.insertData(map); } else { ArrayList<Map<String, Object>> list = (ArrayList<Map<String, Object>>) mapper.readValue(data, List. class ); if (list != null && list.size() > 0 ) { //처음부터 등록시 마지막 등록한게 최우선 등록하게 되므로 거꾸로 for문을 돌림 for ( int i= list.size() - 1 ; i >= 0 ; i--) { dao.insertData(list.get(i)); } } } return hmap; } //update logic @RequestMapping ( "/updateData" ) public @ResponseBody Map<String , Object> updateData(HttpServletRequest request) throws JsonParseException, JsonMappingException, IOException, SQLException { Map<String, Object> hmap = new HashMap<String, Object>(); hmap.put( "success" , true ); String data = request.getParameter( "data" ); ObjectMapper mapper = new ObjectMapper(); if (data.substring( 0 , 1 ).equals( "{" )) { Map<String, Object> map = mapper.readValue(data, Map. class ); dao.updateData(map); } else { ArrayList<Map<String, Object>> list = (ArrayList<Map<String, Object>>) mapper.readValue(data, List. class ); if (list != null && list.size() > 0 ) { //upate 순서는 상관없으므로 for (Map<String, Object> map : list) { dao.updateData(map); } } } return hmap; } //delete logic @RequestMapping ( "/deleteData" ) public @ResponseBody Map<String , Object> deleteData(HttpServletRequest request) throws JsonParseException, JsonMappingException, IOException, SQLException { Map<String, Object> hmap = new HashMap<String, Object>(); hmap.put( "success" , true ); String data = request.getParameter( "data" ); ObjectMapper mapper = new ObjectMapper(); if (data.substring( 0 , 1 ).equals( "{" )) { Map<String, Object> map = mapper.readValue(data, Map. class ); dao.deleteData(map); } else { ArrayList<Map<String, Object>> list = (ArrayList<Map<String, Object>>) mapper.readValue(data, List. class ); if (list != null && list.size() > 0 ) { //delete 순서는 상관없으므로 for (Map<String, Object> map : list) { dao.deleteData(map); } } } return hmap; } |
각 DB호출하는 쿼리로직은 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | < select id = "listData" resultType = "java.util.Map" > SELECT idx,title, name FROM grid ORDER BY idx DESC </ select > < insert id = "insertData" parameterType = "java.util.Map" > INSERT INTO grid(title,name) VALUES(#{title},#{name}) </ insert > < update id = "updateData" parameterType = "java.util.Map" > UPDATE grid SET title = #{title}, name = #{name} WHERE idx = #{idx} </ update > < delete id = "deleteData" parameterType = "java.util.Map" > DELETE FROM grid WHERE idx = #{idx} </ delete > |
이제 ExtJS MVC를 이용한 "GRID CRUD" 관련 코드작성은 완료되었습니다.
이제 실행을 해보도록 하겠습니다.
위 데이터 3개는 임의로 테이블 생성 후
insert한 데이터에 대한 값을 출력한 결과입니다.
추가 버튼 클릭 후 제목과 이름에 textfield 로 원하는 값을 입력 후
UPDATE 버튼을 클릭합니다.
※ update 버튼 클릭한다고 데이터 통신이 되지 않습니다.
임의로 화면상에 쌓아두고 있는 상태입니다. ※
추가버튼을 이용하여 가상의 데이터 2개를 삽입 후
기존 데이터를 선택하여 각 컬럼을 수정하였습니다.
기존 데이터를 선택 후 삭제버튼을 클릭한 최종 화면입니다.
화면에 보시다시피 기존 데이터를 제외한 나머지에 각 컬럼 좌측상단을 보시면
빨칸화살표같은 것이 있는데 이부분은 임의로 등록이 되었거나 수정이 되었다는 뜻입니다.
그럼 이제 적용 버튼을 클릭하여 데이터 통신이 일어난 후의 결과 화면을 보도록 하겠습니다.
신규로 넣었던 데이터에 대한 번호시퀀스 값이 자동으로 적용되며
수정된 값도 정상적으로 반영되어 최종값이 로드되었습니다.
다음장은 기존 소스에 이어 그리드 페이징 및 각 버튼에 대한 기능들을
컨트롤러에 담아보도록 하겠습니다.
by 개발로짜
ExtJS 강좌 - ExtJS5 MVC 구조를 이용한 간단 그리드 CRUD 알아보기(2) (5) | 2015.01.07 |
---|---|
Spring @ResposeBody를 이용하여 JSON Response 할때 IE에서 다운로드현상 해결법 (4) | 2014.12.07 |
ExtJS 강좌 - ExtJS5 MVC 구조 잡아보기(View/Controller + Model+Store 추가) (0) | 2014.11.26 |
ExtJS 강좌 - ExtJS5 MVC 구조 잡아보기(View+Controller 연동) (2) | 2014.11.26 |
ExtJS 강좌 - Sencha CMD로 ExtJS 구조 생성하여 연동테스트 해보기 (1) | 2014.11.24 |
이전 Spring3 + ExtJS 파일업로드 관련하여 포스팅을 한 적이 있습니다.
2014/10/28 - [웹개발강좌/ExtJS] - ExtJS 강좌 - 파일필드를 이용하여 파일업로드하기(html5를 이용한 다중파일 포함)
"Deoki"님께서 질문주신 결과
Spring의 @ResponseBody + Jackson JSON 라이브러리를 이용하여
JSON 파싱한 결과
크롬에서는 정상적으로 JSON 값을 받아왔으나
IE에서는 다운로드가 되는 현상이 발생되었습니다.
이러한 현상이 발생하는 이유는
JacksonMessageConverter의 응답타입이 "application/json" 이어서
IE에서는 정상적으로 동작되지 않는 것이었습니다.
그래서 응답타입을 "text/plain"형태로 설정을 변경을 해주어야 합니다.
크롬에서만 작업하다보니 IE에서 문제가 발생한거라는 것을 몰랐었네요;;
만약 "json-simple" 또는 "json-lib" 와같이 파싱해주는 라이브러리 사용시
response.setContentType을 "text/plain" 으로 설정해주면 문제 없이 IE/크롬 등
모든 브라우저에서 정상작동하는 것이라 신경을 쓰지 않았었는데;;;
상단 포스팅 링크의 코드에 대한 실행결과를 확인해 보도록 하겠습니다.
크롬은 정상적으로 메시지 창이 출력되는 반면,
IE에서는 서버에서 응답받은 결과값이 파일로 다운로드처리가 되었습니다.
그럼 이 부분을 해결하기 위하여
1 | < mvc:annotation-driven /> |
상단 기존 태그를 다음과 같이 코드 변경을 해주도록 합니다.
1 2 3 4 5 6 7 | < mvc:annotation-driven > < mvc:message-converters > < bean class = "org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" > < property name = "supportedMediaTypes" value = "text/plain;charset=UTF-8" /> </ bean > </ mvc:message-converters > </ mvc:annotation-driven > |
위와같이 설정을 해주었다면 다시한번 IE에서 동작을 시켜보도록 하겠습니다.
위와같이 정상적으로 업로드된 파일에 대하여
정상적으로 JSON OBJECT를 받아오는 결과를 확인 할 수 있었습니다.
Spring의 @ResponseBody를 이용한 JSON 구현할때
text/plain 을 적용해주기 위해서는 "mvc:annotation-driven" 태그를
위와같이 적용을 해주는 것이 이 포스팅의 핵심내용입니다.
by 개발로짜
ExtJS 강좌 - ExtJS5 MVC 구조를 이용한 간단 그리드 CRUD 알아보기(2) (5) | 2015.01.07 |
---|---|
ExtJS 강좌 - ExtJS5 MVC 구조를 이용한 간단 그리드 CRUD 알아보기(1) (13) | 2014.12.29 |
ExtJS 강좌 - ExtJS5 MVC 구조 잡아보기(View/Controller + Model+Store 추가) (0) | 2014.11.26 |
ExtJS 강좌 - ExtJS5 MVC 구조 잡아보기(View+Controller 연동) (2) | 2014.11.26 |
ExtJS 강좌 - Sencha CMD로 ExtJS 구조 생성하여 연동테스트 해보기 (1) | 2014.11.24 |
내 블로그 - 관리자 홈 전환 |
Q
Q
|
---|---|
새 글 쓰기 |
W
W
|
글 수정 (권한 있는 경우) |
E
E
|
---|---|
댓글 영역으로 이동 |
C
C
|
이 페이지의 URL 복사 |
S
S
|
---|---|
맨 위로 이동 |
T
T
|
티스토리 홈 이동 |
H
H
|
단축키 안내 |
Shift + /
⇧ + /
|
* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.