이번에는 이전 강좌에서 좌측 메뉴를 완성해보겠다.
좌측 메뉴는 이전강좌에서 panel을 하나 추가하여 "사용자 관리"라는 메뉴를 하나
강제로 생성 시켰다. 이번에는 ajax를 통해 메뉴정보를 가져올 수 있도록 store를 구성하고
해당 store에서 값을 가져와 메뉴를 구성하기까지 과정을 알아보자.
아래 그림처럼 store와 model폴더에 파일을 만들어 놓자.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 | /** * Date : 2012.11.30 * Desc : 프로그램 정보를 표현할 모델 클래스 */ Ext.define( 'ria.model.system.Program' , { extend: 'Ext.data.Model' , // extend fields: [ 'pgm_id' , 'pgm_nm' , 'pgm_syscd' , 'pgm_sysnm' , 'pgm_class' , 'pgm_icon' , 'pgm_sysicon' , 'group_id' , 'group_nm' , 'group_status_cd' , 'group_status_nm' , 'group_pgm_status_nm' ] }); /** * Date : 2012.11.30 * Desc : 좌측 시스템 리스트 * 여기서 중분류 정도의 시스템 리스틀 가져온다. */ Ext.define( 'ria.store.system.Systems' , { extend: 'Ext.data.Store' , // 당연히 store상속 autoLoad : false , // 자동 로드는 꺼놓자. model: 'ria.model.system.Program' , // 모델 세팅 proxy: { type: 'ajax' , // json폴더를 루트에 만들고 systemlist.json이라는 파일를 통해 // 시스템 리스트를 받을 수 있다. url: '/json/systemlist.json' , reader: { type: 'json' , root: 'entitys' , totalProperty: 'totalCount' , messageProperty: 'message' }, listeners: { exception: function (proxy, response, operation){ // 나중에 구현할 부분 모든 ajax 통신에 공통으로 쓸 수 있는 // 에러 캐치 함수를 만들 것이다. } } } }); // 이제 위의 store에서 호출하는 json파일을 만듭니다. // 현재는 아래와 같이 만들어져 있지만 실제로는 디비의 값을 가져와 이 파일의 내용을 출력하도록 // 만 서버쪽 개발만 하면 클라이언트쪽은 호출주소외에 전혀 손댈때가 없게 됩니다. /** ** Date : 2012.11.30 ** Desc : 시스템 리스트 제공 ** Posn : /json/systemlist.json **/ { "entitys" :[{ "pgm_syscd" : "F001" , "pgm_sysicon" : "grid" , "pgm_sysnm" : "거래처관리" }, { "pgm_syscd" : "F002" , "pgm_sysicon" : "grid" , "pgm_sysnm" : "영업일지" }, { "pgm_syscd" : "F003" , "pgm_sysicon" : "grid" , "pgm_sysnm" : "서류관리" }, { "pgm_syscd" : "F004" , "pgm_sysicon" : "grid" , "pgm_sysnm" : "통보서관리" }, { "pgm_syscd" : "F005" , "pgm_sysicon" : "grid" , "pgm_sysnm" : "현황관리" }, { "pgm_syscd" : "F007" , "pgm_sysicon" : "grid" , "pgm_sysnm" : "실적관리" }, { "pgm_syscd" : "S002" , "pgm_sysicon" : "grid" , "pgm_sysnm" : "패키지관리" }], "errMsg" : "" , "errTitle" : "검색결과" , "message" : "" , "success" : true , "totalCount" : "8" } |
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 | // app/controller/FrameController.js 를 수정한다. // views, refs, onLaunch를 확인하자. Ext.define( 'ria.controller.FrameController' , { extend: 'Ext.app.Controller' , stores: [ 'system.Systems' ], views: [ 'ria.view.frame.WestMenuPanel' , 'ria.view.frame.WestMenuDataViewPanel' ], // 꼭 명시되어야함, 명시하지 않을 경우 require를 이용해야합. refs: [ {ref: 'westMenu' , selector: 'WestMenuPanel' } ], init: function () { this .control({ }); }, onLaunch: function () { // refs의 ref명으로 뷰를 찾아온다. var menu = this .getWestMenu(); var store = this .getStore( 'system.Systems' ); // store를 호출 store.load( function (record, b, c){ // 아직 로드전이므로 로드한다.이때 json파일 호출 store.each( function (rec){ // store를 탐색하여 menu.add({ // 메뉴가 추가될 패널에 아래와 같이 패널을 추가. xtype: 'WestMenuDataViewPanel' , title:rec.get( 'pgm_sysnm' ), // 시스템명 fnc_pgm_syscd:rec.get( 'pgm_syscd' ), // 시스템 코드 iconCls:rec.get( 'pgm_sysicon' ) // 아이콘이 있다면 표기 }); }); }); } }); // 위에서 사용한 메뉴 패널 // app/view/frame/WestMenuPanel.js를 추가합니다. Ext.define( 'ria.view.frame.WestMenuPanel' ,{ extend : 'Ext.panel.Panel' , alias : 'widget.WestMenuPanel' , layout: 'accordion' , // 이놈 하위에 추가될 dataview또한 accordion collapsible: true , split: true , title : '^^' , activeItem: 0, initComponent: function () { this .callParent(arguments); } }); |
이제 추가된 시스템 패널 중에 열려 있는 패널이 어떤 패널인지 확인 해보자. westMenuPanel에 panel이 accodion레이아웃으로
추가되었으므로 그중 열려 있는 놈을 찾는 것이다.
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 | Ext.define( 'ria.controller.FrameController' , { . . . init: function () { this .control({ // step1. 좌측 매뉴에 추가된 패널 즉 시스템 패널에 대한 이벤트 추가. 'WestMenuPanel > WestMenuDataViewPanel' : { afterrender: this .firstSelect, expand: this .onItemClicked } }); }, /** * step2. afterrender는 추가된 패널 별로 render된 이후에 호출한다. * 추가된 시스템 패널 중에 열려 있는지 확인하면 맨처음 하나만 열리게 된다. * 그 열려있는 시스템 패널에 하위 프로그램이 로딩되어 추가될 수 있도록 코딩해야한다. **/ firstSelect : function (panel){ console.log( '추가된 시스템 패널' , panel.xtype, panel.title, panel.collapsed); if (!panel.collapsed){ // accordion 레이아웃에 패널이 추가되면 디폴트로 맨처음 패널이 // 패널이 펼쳐져 있게 되고 이놈을 찾아서 해당 시스템 이하의 프로그램을 불러올 수 있도록 코딩한다. console.log( '추가된 시스템 패널 중 접히지 않은 패널 :' , panel.title, panel.collapsed); } }, onItemClicked : function (a, b, c){ console.log(a,b,c); }, |
콘솔에 출력해 보면 좌측 시스템 패널중에 열려 있는 패널은 "거래처관리"라는 것을 알 수 있다.
다음으로는 추가된 패널을 클릭 했을 때 즉 현재는 click이 아니라 expand이벤트 이므로 이 이벤트가 전달하는 arguments가 뭔지 알아보자. doc.sencha.com에서 아래와 같이 api를 확인해 보자. 역시나 expand이벤트 또한 panel객체 자기자신을 전달하고 있다.
이제 expand이벤트를 구현할 함수 (onItemClick)을 구현해 보자.
프로그램 store를 준비한다.
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 | /** ** Date : 2012.11.30 ** Desc : 시스템이하 프로그램 리스트 제공 ** Posn : /json/programlist.json **/ { "entitys" :[{ "pgm_class" : "ria.view.pgms.RiaAppMain01" , "pgm_icon" : "grid" , "pgm_nm" : "하위 프로그램1" }, { "pgm_class" : "ria.view.pgms.RiaAppMain02" , "pgm_icon" : "grid" , "pgm_nm" : "하위 프로그램2" }, { "pgm_class" : "ria.view.pgms.RiaAppMain03" , "pgm_icon" : "grid" , "pgm_nm" : "하위 프로그램3" }, { "pgm_class" : "ria.view.pgms.RiaAppMain04" , "pgm_icon" : "grid" , "pgm_nm" : "하위 프로그램4" }, { "pgm_class" : "ria.view.pgms.RiaAppMain05" , "pgm_icon" : "grid" , "pgm_nm" : "하위 프로그램5" }, { "pgm_class" : "ria.view.pgms.RiaAppMain06" , "pgm_icon" : "grid" , "pgm_nm" : "하위 프로그램6" } ], "errMsg" : "" , "errTitle" : "검색결과" , "message" : "" , "success" : true , "totalCount" : "2" } /** * Date : 2012.11.30 * Desc : 좌측 시스템 이하 프로그램 리스트 * 여기서 최하위 단 프로그램 리스트를 가져온다. */ Ext.define( 'ria.store.system.Programs' , { extend: 'Ext.data.Store' , // 당연히 store상속 autoLoad : false , // 자동 로드는 꺼놓자. model: 'ria.model.system.Program' , // 모델은 동일하게 사용 세팅 proxy: { type: 'ajax' , // json폴더를 루트에 만들고 programlist.json이라는 파일를 통해 // 시스템 리스트를 받을 수 있다. url: '/json/programlist.json' , reader: { type: 'json' , root: 'entitys' , totalProperty: 'totalCount' , messageProperty: 'message' }, listeners: { exception: function (proxy, response, operation){ // 나중에 구현할 부분 모든 ajax 통신에 공통으로 쓸 수 있는 // 에러 캐치 함수를 만들 것이다. } } } }); // 이하 컨트롤러의 onItemClicked 함수 구현 /** * Step3. 시스템 패널을 클릭 할 때 마다 expand이벤트가 호출 된다. * 이 때 클릭되어 expand된 패널 위에 하위 프로그램을 출력하면 된다. * @param a * @param b * @param c */ onItemClicked : function (panel){ var store ; if (!panel.collapsed){ // 패널이 접히지 않은 놈을 찾는다. // 아래 코드를 보면 시스템 패널은 dataview를 가지고 있다. 이 dataview는 // 해당 패널이 가지고 있는 시스템 아이디에 해당하는 프로그램을 표현하게 된다. // dataview는 expand될 때 하위 프로그램을 가져오도록 했기 때문에 // 이미 가져왔다면 다시 서버에 로드 되지 않도록 한다. 굳이 매번 쓸데없이 // 서버에 다녀오지 않게 하기 위함. if (panel.down( 'dataview' ).store.getTotalCount() > 0) return ; // 아래 코드에서는 Ext.create를 사용하였다. // 이는 컨트롤러에 아래 스토어를 명시하지 않았기 때문인데 명시하지 않은 것은. // 프로그램 리스트 store가 시스템별로 여러개 존재하므로 컨트롤러에 명시할 경우 // 모든 시스템 패널이 동일한 프로그램을 보게 되므로 각기 다르게 생성하여 // 공유하지 못하도록 하기 위함이다. store = Ext.create( 'ria.store.system.Programs' ); // 재활용 되는 것을 막는다. store.load({ params: { // 아래 코드는 시스템 패널이 가지고 있는 시스템 아이디를 프로그램 store에 전달하는 // 코드다 이렇게 해야 각기 시스템 패널별로 해당 시스템 이하의 프로그램을 가져올수 있다. pgm_syscd: panel.pgm_syscd } }); // 최종 시스템 패널 안으 dataview에 프로그램 store를 바인딩 한다. panel.down( 'dataview' ).bindStore(store); } return store; }, |
그런데 최초에는 거래처 관리에 프로그램이 비어 있다. 클릭 하고 다시 클릭하면 프로그램이 보이지만 처음엔 보이지 않는다.
이 부분은 firstSelect 함수에서 해결해 보자. 이 함수는 afterrender로 가 될 때 한번 호출 되므로 이 때 열려진 패널에 프로그램이
세팅되도록 해보겠다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** * step2. afterrender는 추가된 패널 별로 render된 이후에 호출한다. * 추가된 시스템 패널 중에 열려 있는지 확인하면 맨처음 하나만 열리게 된다. * 그 열려있는 시스템 패널에 하위 프로그램이 로딩되어 추가될 수 있도록 코딩해야한다. **/ firstSelect : function (panel){ console.log( '추가된 시스템 패널' , panel.xtype, panel.title, panel.collapsed); if (!panel.collapsed){ // accordion 레이아웃에 패널이 추가되면 디폴트로 맨처음 패널이 // 패널이 펼쳐져 있게 되고 이놈을 찾아서 해당 시스템 이하의 프로그램을 불러올 수 있도록 코딩한다. console.log( '추가된 시스템 패널 중 접히지 않은 패널 :' , panel.title, panel.collapsed); // Step4. // 이제 시스템 패널이 rendering된 후에 열려있는 맨처음 시스템 패널에 프로그램이 자동세팅되도록 해야한다. // expand이벤트를 통해 클릭 시마다 프로그램이 추가되지만 맨처음 시스템 패널은 비어 있으므로 채우도록 코딩한다. // onItemClicked함수는 시스템 패널의 dataview에 store를 바인딩하는 기능을 한다. var store = this .onItemClicked(panel); } }, |
이제 main.html파일을 열고 하위프로그램에서 사용할 css를 추가합니다.
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 | // main.html < script type = "text/javascript" src = "app.js" >< / script > < style type = "text/css" > .feed { width: 16px; height: 16px; background-image: url(/common/images/icon/rss.gif) !important; } .feed-picker-url { float: left; width: 425px; } .feed-picker-title { /* float: left;*/ color: #777; font-size: 10px; } .feed-list { padding: 0 3px 0 3px; } .feed-list-item { margin-top: 3px; padding-left: 20px; font-size: 11px; line-height: 20px; cursor: pointer; background: url(/common/images/icon/rss.gif) no-repeat 0 2px; border: 1px solid #fff; } .feed-list .x-item-selected { font-weight: bold; color: #15428B; background-color: #DFE8F6; border: 1px dotted #A3BAE9; } .feed-list-item-hover { } < / style > < / head > < body > |
이제 프로그램에 예쁘게 css가 적용되었다. ^^
'자바스크립트 > Ext JS' 카테고리의 다른 글
ExtJS를 활용한 Ria 어플리케이션 구축하기 - 6(예고) (3) | 2012.12.12 |
---|---|
ExtJS를 활용한 Ria 어플리케이션 구축하기 - 5 (0) | 2012.12.07 |
ExtJS를 활용한 Ria 어플리케이션 구축하기 - 3 (16) | 2012.07.22 |
ExtJS를 활용한 Ria 어플리케이션 구축하기 - 2 (3) | 2012.07.22 |
ExtJS를 활용한 Ria Application 만들기 (1) | 2012.07.21 |