오랫만에 ExtJS 강의를 올리게 되었다..
마땅히 프로젝트 주제를 정하고 정하다가 결국은 심플하게 하기로 정하였다;;;
이번 다룰 주제는 ExtJS MVC 기반을 이용하여 간단? 회원관리 테이블을 만들어볼 예정이다.
해당 주제에서 핵심은 GRID를 통하여 DB에 대한 CRUD 기능을 모두 적용하는 것임.
전에는 GRID에 대하여 LIST 출력하는 내용만 기술하였는데 이번 프로젝트를 통해서
CRUD를 모두 적용해보도록 하겠음.
컴포넌트 설정 및 내용에 대하여는 이전 포스팅에 여러가지 올려놨으니 순서대로 차근차근
보시는걸 추천드림.
우선적으로 웹소스 + DB 커넥션에 대한 설정은 제외 하도록 하겠음.
자 그럼 그리드를 이용한 CRUD 설명 GO!
1. 자신이 작업하려는 환경의 DB에 다음과 같은 테이블 생성!! (MYSQL 기준)
CREATE TABLE member( seq INT NOT NULL AUTO_INCREMENT COMMENT '회원번호', member_name VARCHAR(20) NOT NULL COMMENT '회원이름', member_birth VARCHAR(8) NOT NULL COMMENT '회원생년월일', member_mobile VARCHAR(11) NOT NULL COMMENT '회원연락처', create_date DATETIME NOT NULL COMMENT '등록일', PRIMARY KEY (`seq`) ) ENGINE=INNODB CHARSET=utf8;
2. 지난 시간에 설정한 MVC 구조기준으로 controller/model/store/view를 새로구성
하기 위해 파일들을 새로 생성해보았다.
화면의 mvc.js에서 변경된 것이 있다고 한다면 기존에는 controllers의 값을
'MVCController' -> 'MemberController' 이걸로 변경한것이 전부다.
name 명칭을 바꿔주면 cotroller/model/store/view에 대한 모든 define 명칭을 변경해주는것이
귀찮아서 mvc로 냅둔상태...
자~ TABLE 도 생성했으니 1차적으로 MemberModel.js를 먼저 정의해두도록 하자
흐름방식을 model -> store -> view -> viewport -> controller 로 진행하는것이 수월할듯함...
1. model 관련
그냥 단순하게 crud 를 확인하고자 하는것이니 fields의 명칭은 테이블의 명칭과
맞추어 주었다.
Ext.define('mvc.model.MemberModel', { extend: 'Ext.data.Model', fields: [ {name: 'seq', type: 'int'}, {name: 'member_name', type: 'string'}, {name: 'member_birth', type: 'string'}, {name: 'member_mobile', type: 'string'}, {name: 'create_date', type: 'date'} /*{name: 'create_date', type: 'string'}*/ ] });
2. store 관련
Model을 사용할 Store부분을 보도록 하자
Ext.define('mvc.store.MemberStore', { extend: 'Ext.data.Store', model: 'mvc.model.MemberModel', autoLoad: true, proxy: { type: 'ajax', api: { // insert page create : '/create', // select page read: '/list', // update page update : '/update', // delete page destroy : '/delete' }, //select option reader: { type: 'json', successProperty: 'success', rootProperty: 'items' }, //create,update,delete option writer: { type: 'json', //그리드 row의 모든값 전송 writeAllFields: true, //필수속성값 encode : true, //server (request param id) rootProperty: 'data' } } });
뭔가 드~~럽게 많이 추가되었다.
예전 grid 페이징을 했을경우, proxy -> api가 read랑 proxy의 reader 속성만 다루었었는데
추가로 api의 속성들이 create / read / destroy 이 세개가 추가되었고 writer 라는 속성이 추가
되었다.
이와같이 추가된 속성들은 insert / update / delete db 처리 작업을 하기위하여 필요한 놈들이다 +_+ ㅋㅋㅋ
3. view 관련
gridpanel 을 view에 정의해주도록 하자
Ext.define('mvc.view.MemberGrid', { extend: 'Ext.grid.Panel', alias : 'widget.memberGrid', store : 'MemberStore', columns: [ { dataIndex : 'seq', text : '회원번호' }, { dataIndex : 'member_name', text : '회원이름', editor : 'textfield' }, { dataIndex : 'member_birth', text : '생년월일', editor : 'textfield' }, { dataIndex : 'member_mobile', text : '연락처', editor : 'textfield' }, { dataIndex : 'create_date', text : '등록일', flex : 1 } ], //그리드 컬럼을 수정하기위하여 필요한 ExtJS 관련 플러그인 {clicksToEdit: 1} << 제거후 //수정하려면 컬럼 더블클릭해야함 해당옵션은 한번클릭으로 그리드 컬럼 수정가능 plugins: [new Ext.grid.plugin.CellEditing({clicksToEdit: 1})], tbar : [ { //추가버튼 xtype :'button', text : '추가', id : 'addBtn' }, { //삭제버튼 xtype :'button', text : '삭제', id : 'removeBtn' }, { //적용버튼 xtype :'button', text : '적용', id : 'syncBtn' } ], initComponent: function() { this.callParent(); } });
4.컨트롤러 관련
Ext.define('mvc.controller.MemberController', { //기본상속 extend: 'Ext.app.Controller', refs: [ { ref: 'memberGrid', selector: 'memberGrid' } ], stores : ['MemberStore'], views: ['MemberGrid'], init: function() { this.control({ //멤버그리드 컴포넌트내에 존재하는 버튼셀렉터 'memberGrid button' : { //클릭이벤트 발생시 controller에 존재하는 //gridHandleButton 함수를 호출 click : this.gridHandleButton } }); }, gridHandleButton : function(btn) { //그리드 객체 var grid = this.getMemberGrid(); //그리드 -> 저장공간 객체 var gridStore = grid.getStore(); //그리드 행 추가버튼 클릭 if(btn.getId() == "addBtn") { //membermodel var rec = new mvc.model.MemberModel({ seq: '', member_name : '', member_birth: '', member_mobile: '', create_date: '' }); //store에 로우 추가 gridStore.insert(0, rec); //에디트 시작포커스 잡기 (없으면 단순 로우만 추가) grid.plugins[0].startEditByPosition({ row: 0, column: 1 }); } else if(btn.getId() == "removeBtn") { //그리드 로우 삭제 grid.getStore().remove(grid.getSelectionModel().getSelection()); } else if(btn.getId() == "syncBtn") { //create,update,destroy 처리를 한다 grid.getStore().sync({ callback : function(){ //insert/update/delete 후에 리스트 재호출 grid.getStore().reload(); } }); } } });
현 예제에서는 오류 관련은 다루지 않는다.
sync 일 경우 store에서 정의했던 create/update/destroy 속성을 각각호출한다.
한꺼번에 호출할수도 있는데 조금 복잡하므로 추후 시간이 나면 다루도록 하겠음
crud의 핵심은 store에 정의된 proxy url영역이고 컨트롤러의 store load/sync 함수이다!
list는 화면에 출력해주는 것이므로 reader -> rootProperty의 items가 response 해주는
json root 객체인 셈이다.
db 호출후 서버에서 클라이언트로 응답해주는 json 객체의 json 문자열은 다음과 같다.
파싱관련은 본인이 사용하는 json object 생성 라이브러리를 이용하여 파싱해주도록 하자
// read url 호출시 list json객체 { "items": [ {"seq":"9","member_name":"333","member_birth":"333","member_mobile":"333","create_date":"2014-07-1623:20:35.0"}, {"seq":"7","member_name":"11","member_birth":"11","member_mobile":"11","create_date":"2014-07-1623:20:22.0"} ] }
거꾸로 create/update/destroy에서 정해준 writer 속성의 rootProperty로 정해준 키값으로 서버
에서 데이터를 request 하게되면json 문자열로 파라미터를 받을수 있다.
writer의 rootProperty 값을 data 정의해준거면 서버에서 request.getParameter("data") 로
받으면 다음처럼 데이터를 받을 수 있다.
//seq는 자동증가값이므로 입력할 필요없다 // create_date 역시 null인대 쿼리문 자체에서 now()로 주므로 의미가 없다. [ {"seq":0,"member_name":"222","member_birth":"444","member_mobile":"555","create_date":null,"id":"mvc.model.MemberModel-4"}, {"seq":0,"member_name":"111","member_birth":"333","member_mobile":"444","create_date":null,"id":"mvc.model.MemberModel-3"} ]
writer의 json 속성중 id 는 별의미 없다.
마지막으로 서버에서 가공해줘야 하는 순서는 다음과 같다.
1. 문자열 json을 json object 또는 json array 로 변경해주어야함
2. json array 및 json object에 대하여 쿼리를 가공하여 db처리를 해준다.
해당 샘플은 본인이 테스트로 만든 서버 로직이다.
(json-simple library 를 이용하였다)
////////////////////// "/create 호출 페이지" /////////////////////////
//object일수도 있고 array일수도 있다. object 변환후 json array에 담는다. JSONObject jsonObj = null; JSONObject jsonObject = null; JSONArray jsonArr = null; String data = request.getParameter("data"); if(data.substring(0,1).equals("{")) { jsonObject = JSONObject.fromObject(JSONSerializer.toJSON(data)); jsonArr = new JSONArray(); jsonArr.add(jsonObject); } else if(data.substring(0,1).equals("[")) { jsonArr = JSONArray.fromObject(data); } if(jsonArr.size() > 0){ for(int i=0; i<jsonArr.size(); i++) { jsonObj = (JSONObject)jsonArr.get(i); String query = ""; query += " INSERT INTO member(member_name,member_birth,member_mobile,create_date) "; query += " VALUES('"+jsonObj.get("member_name")+"','"+jsonObj.get("member_birth")+"','"+jsonObj.get("member_mobile")+"',now()) "; service.executeQuery(query); } } jsonObj = new JSONObject(); jsonObj.put("success", true); PrintWriter pw = response.getWriter(); pw.print(jsonObj); pw.flush(); pw.close();
위와 같이 작업한결과 이상없이 동작하는것을 확인하였다.
영상으로 동작과정을 보고 마무리를 하도록 하겠음!!
도움이 되셨다면 공감클릭! 궁금하신점은 댓글!!
[ExtJS강좌 27] 다음(DAUM) 우편번호(주소검색) 서비스 소개 + ExtJS를 이용하여 주소검색 해보기 (0) | 2014.08.25 |
---|---|
[ExtJS강좌 26] 비동기 Ajax 사용하기 - (Ext.Ajax.request) (8) | 2014.08.25 |
[일반 리스트 vs ExtJS 그리드 속도비교] (8) | 2014.07.08 |
[ExtJS강좌 24] MVC 기반으로 컴포넌트 동작시키기 (3) (0) | 2014.07.07 |
[ExtJS강좌 23] MVC 기반으로 컴포넌트 동작시키기 (2) (0) | 2014.07.04 |