이번에는 이전 강좌에서 좌측 메뉴를 완성해보겠다.
좌측 메뉴는 이전강좌에서 panel을 하나 추가하여 "사용자 관리"라는 메뉴를 하나
강제로 생성 시켰다. 이번에는 ajax를 통해 메뉴정보를 가져올 수 있도록 store를 구성하고
해당 store에서 값을 가져와 메뉴를 구성하기까지 과정을 알아보자.
아래 그림처럼 store와 model폴더에 파일을 만들어 놓자.
/** * 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"}
// 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레이아웃으로
추가되었으므로 그중 열려 있는 놈을 찾는 것이다.
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를 준비한다.
/** ** 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로 가 될 때 한번 호출 되므로 이 때 열려진 패널에 프로그램이
세팅되도록 해보겠다.
/** * 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를 추가합니다.
// 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 |