자바스크립트/Ext JS2013. 3. 9. 13:50

ExtJs 포럼을 훌터 보던 중 재미나고 필요한 기능을 제공하는 사이트를 발견했다.

이 사이트는 json String 을 트리형태로 보여주고 비교까지 가능한 기능을 제공한다.

브라우저에서 실행되는 터라 너무 많은 양의 데이터는 버거워 보이지만 실무에서

json 을 직접 눈으로 확인해야하는 경우가 있고 이런 경우 이사이트에 json을 

입력하고 눈으로 확인하면 한결 편하겠다는 생각이 든다.



Posted by 베니94
자바스크립트/Ext JS2013. 3. 8. 23:13

어제 우리 파트원이 내게 하는말이 IE8에서 ExtJS가 미쳐간다고 한다. 다 괜찮은데 IE8을 대부분 사용하는 고객사에서

컴플레인이 계속 들어오고 있다고 한다. 

문제는 TextArea에 계속 문자열을 입력하다 보면 IE8에서만 아래 동영상처럼 혼자 미친듯이 제어를 못하는

모습이 연출되는 것이다.


원인파악에 들어가서 2시간 만에 찾아낸 원인은 바로 <!DOCTYPE html> 이것이였다. app.js를 호출하는 html에

<!DOCTYPE html> 이것이 들어가 있어서 였다. 설마 했지만 이 코드를 제거하자 언제 그랬냐는 듯 정상 작동을 하였다.


DOCTYPE 즉 DTD (Document Type Definition)을 정확히 명시하지 않아서 이다. DTD가 명확하지 않을 경우

브라우저는 임의로 DTD를 해석하게 되고 의도치 않은 동작을 하게 되는 것 같다.

이런 경우에는 DTD를 정확히 명시하거나 그러기 힘들 경우 아예 삭제하는 것이 좋겠다.

브라우저는 html의 DOCTYPE으로 이 문서가 어떤 형식의 문서인지 구별하게 된다. IE에 경우 유난히 심하다고 할 수 있다.

동일한 소스도 DOCTYPE을 어떻게 명시하느냐에 따라 보여지는 모습이 전혀 다를 수 있다는 것을 인지해야한다.


뭐든 정확히 알고 쓰는게 좋다며 살짝 혼을 내긴 했지만 나 또한 이부분이 문제를 일으키리라고는 

생각지 못했으니 좋은 경험 했다고 생각해야 겠다.



Posted by 베니94
자바스크립트/Ext JS2013. 2. 24. 10:15

ExtJS강의교안(배포판).pdf

어제 ExtJS오프라인 강의를 잘 마쳤습니다.

오신분들 감사드리고 다음에 또 뵙겠습니다.


'자바스크립트 > Ext JS' 카테고리의 다른 글

Json 비교 사이트  (0) 2013.03.09
ExtJS4 IE8 textarea 버그?  (1) 2013.03.08
ExtJs 오프라인 강좌진행합니다.  (2) 2013.02.06
강좌 소스 올립니다.  (4) 2013.01.18
ExtJS 오픈라인 강의를 할까 생각중입니다.  (10) 2013.01.18
Posted by 베니94
자바스크립트/Ext JS2013. 2. 6. 23:10

ExtJS 오프라인 강좌 진행합니다.


일시 : 2/23 토요일 오후 7~9시

장소 : 토즈강남타워점


많은 참석 부탁드립니다.


아래에서 참석 신청해주세요

http://onoffmix.com/event/12445




Posted by 베니94
Tools2013. 2. 2. 22:53

PowerMockUp 소개

오늘은 웹 화면 설계 하는 데 있어 괜찮은 툴 하나를 소개 하려고 합니다. 가뜩이나 웹 개발 하는데 설계부터 개발, 테스트까지 많은 툴을 사용하는데... 또 다른 툴을 배우자니 우선 거부감 부터 생기시는 분들이 있으실 텐데요... 이 PowerMockUp은 MS Powerpoint에 Extention으로 도구가 생기는 쉽고 웹 지향적인 웹 기획시 가장 괜찮은 툴이 아닐까 생각이 되네요.. 기존에는 MS Visio로 화면단을 만들어서 했지만 너무 딱딱하고.... CS 느낌이 풀풀 풍겨서.... 요게 참 매력적이지 않을 수가 없었습니다... 우선 설치 하면 아래와 같은 툴하나가 생깁니다.

 

 

 

요 위의 컴퍼넌트가 생기는데요 아래 화면처럼 Drag & Drop으로 내 머릿속에 있는 화면 설계들을 하나하나 완성 할 수 있습니다.. Trial Version에서는 몇개의 컴퍼넌트만 Open되어있고 나머지는 다 Disabled 상태로 되어있습니다....--;

 

 

위와 같은 화면들을 실제로 설계 할 수 있다는 것이죠 .... 브라우저상 웹 뿐만 아니라 모바일도 가능합니다..

 

 

우와....;; 파워포인트로도 간편하고 빠르게 화면들을 설계해 보실 수가 있습니다...

 

가격 또한 저렴합니다... Single-User Lisence 가.. 약 59 달러 정도 되고.....한화로는 6만 얼마가 되겠군요..

그 외 멀티 유저 라이센스는 아래와 같네요....

 

http://www.powermockup.com/ 로 가시면 좀더 많은 정보를 얻을 수 있습니다. 저처럼 요런식으로 블로그에 담고 주소만 보내면 Single-User Licence key를 준다고 하네요..!!! ^-^

 

'Tools' 카테고리의 다른 글

SublimeText  (0) 2013.06.09
Posted by 베니94
자바스크립트/Ext JS2013. 1. 18. 14:24

강좌 프로젝트 올립니다. 내려받고 실행해보세요.

이제는 강좌 진행과 함께 소스도 함께 올리도록 하겠습니다.



benney.tistory.com.zip


Posted by 베니94
자바스크립트/Ext JS2013. 1. 18. 00:19

오프라인 강의를 하려고 하는데 관심있으신 분들 댓글 달아주시면 감사하겠습니다.


사실 블로그에 올려야할 강좌는 쌓여있습니다. 일에 치이며 먹고살려니 블로그에


글올리는게 쉽지않습니다.


해서 이럴게 아니라 오프라인에서 강의를 해보는 것도 나쁘지 않다는 생각이


듭니다.


장소 : 강남 토즈(아는 곳이 여기밖에 없어서 전 상암인데 멀어도 오시는 분들에 맞출수 있음)

일시 : 미정 단지 시간은 평일저녁7시에서 9시까지(전 주말도 좋긴합니다만..)

내용 : ExtJS가 실무에서 어떻게 사용되는지 소스위주의 시연강의(실습하기에는 시간이 부족할 것 같음)

   MVC모델 중심의 시작부터 배포까지.

인원 : 최소 15명 정도는 되야 하지 않을까요?

비용 : 인당 5만원


댓글로 반응을 보고 해야할지 판단하려고 합니다.


어떠신지요?


Posted by 베니94
자바스크립트/Ext JS2012. 12. 16. 21:18

이전 강좌에서 우리는 좌측 panel안에 davaview를 삽입하여 최초 실행 시 dataview내부 첫번째 data가

선택 되도록 코딩하였습니다.

이번에는 선택 된 데이터뷰가 우측 영역에 어플리케이션으로 나오도록 하고 이 어플리케이션에 그리드와

form을 배치하여 보겠습니다.

우선 컨트롤러가 dataview에서 select한 이벤트를 케치할 수 있도록 아래와 같이 구현합니다.

Ext.define('ria.view.Viewport', {
    extend: 'Ext.container.Viewport',
    layout : 'border',
    items: [
    {
        region: 'center',
        // 기존 panel에서 여러개의 패널을 
        // 붙여야 하므로 tabpanel로 변경합니다.
        xtype: 'tabpanel'
    },{
        region: 'west',
        xtype : 'WestTabPanel',
        width: 200
    }]
});


Ext.define('ria.controller.FrameController', {
.
.
.

   init: function() {
        this.control({
            // step1. 좌측 매뉴에 추가된 패널 즉 시스템 패널에 대한 이벤트 추가.
            'WestMenuPanel &gt; WestMenuDataViewPanel': {
                afterrender: this.firstSelect,
                expand: this.onItemClicked
            }, // select이벤트 잡기.
            'WestMenuDataViewPanel &gt; dataview': {
                select: this.onProgramSelect
            }
         });
    },
    onProgramSelect: function(dataview, record) {
        this.onProgramSelect2(record.get('pgm_class'), record.get('title'));
    },
    /***
     * 최종 클래스명과 탭패널에 추가시 추가할 탭이름을 받는다.
     */
    onProgramSelect2: function(pgm_class, title) {
        var centerpanel =  Ext.ComponentQuery.query('viewport container[region="center"]')[0];
        var tab = centerpanel.down('[tabuniqid=' + pgm_class + title + ']');
        if (!tab) {
            // 아래 클래스를 통해 공통 기능을 구현하고 이 클래스의 item으로 인자로 받아온
            // 클래스를 추가하도록 한다.
            tab = Ext.create('ria.view.pgms.CommonPanel',{
            });
            tab.add(Ext.create(pgm_class,{ region : 'center'}));
            tab.title = title;
            tab.tabuniqid = pgm_class+title;
            centerpanel.add(tab);
        }

        centerpanel.setActiveTab(tab);
    },

위에서 ‘ria.view.pgms.CommonPanel은 모든 프로그램들이 공통적으로 동일한 공통 기능을 갖도록 하기 위해 이 클래스를 부모로 사용하도록 하였다. 이 클래스는 로그아웃, 도움말, 검색 등의 공통적인 기능 가지고 있고 구현해야한다.

Ext.define('ria.view.pgms.CommonPanel',{
    extend : 'Ext.panel.Panel',
    alias : 'widget.CommonPanel',
    layout : 'border',
    initComponent: function() {
        var me = this;

        Ext.apply(this, {
            dockedItems: [{
                xtype: 'toolbar',
                dock: 'top',
                items: [
                    { 
                        xtype: 'button', 
                        text: '도움말',
                        action : 'common.help',
                        listeners : {
                            click : function(a){
                                console.log('도움말 호출', me.uniqid);
                            }
                        }
                    },'-',
                    { 
                        xtype: 'button', 
                        text: 'MyPage',
                        action : 'common.help',
                        listeners : {
                            click : function(a){
                                console.log('도움말 호출', me.uniqid);
                            }
                        }
                    },'-',
                    { 
                        xtype: 'button', 
                        text: '로그아웃',
                        action : 'common.help',
                        listeners : {
                            click : function(a){
                                Ext.Msg.confirm('확인', '로그아웃하시겠습니까?', function(btn) {
                                    if(btn == 'yes') {
                                        console.log('도움말 호출', me.uniqid);
                                        Ext.create('Ext.ux.window.Notification', {
                                            position: 'tr',
                                            useXAxis: true,
                                            cls: 'ux-notification-light',
                                            iconCls: 'ux-notification-icon-information',
                                            closable: false,
                                            title: '확인',
                                            html: '로그아웃되었습니다.',
                                            slideInDuration: 800,
                                            slideBackDuration: 1500,
                                            autoCloseDelay: 4000,
                                            slideInAnimation: 'elasticIn',
                                            slideBackAnimation: 'elasticIn'
                                        }).show();
                                    }
                                });
                            }
                        }
                    },'-',
                    {
                        xtype: 'combo',
                        store: Ext.create('ria.store.system.Programs'),
                        displayField: 'title',
                        typeAhead: false,
                        hideLabel: false,
                        fieldLabel: '검색',
                        labelWidth: 40,
                        hideTrigger:true,
                        width: '400',
                        enableKeyEvents: true,
                        minChars: 2,
                        listConfig: {
                            loadingText: '검색 중입니다....',
                            emptyText: '검색어에 맞는 검색 결과가 없습니다.',

                            // Custom rendering template for each item
                            getInnerTpl: function() {
                                return '< h3 >< span >{[Ext.Date.format(values.input_date, "M j, Y")]}< br />by {input_user_name}< /span >{title}< /h3 >' +
                                    '{excerpt}';
                            }
                        },
                        pageSize: 10,
                        listeners: {
                            select: function(a, b) {
                                console.log(a,b)
                            }

                        }

                    }
                ]
            }]
        });
        me.callParent(arguments);
    }
});
이제 위의 CommonPanel안에 들어갈 즉 선택 되어 보여줘야할 어플리케이션을 구현해 보겠습니다.
위의 코드대로 실행하면 에러가 발생할 것입니다. 우선 아래의 json파일을 보겠습니다.
아래 파일은 dataview에 보여지고 있는 프로그램 리스트입니다. 그 중 첫번째 라인을 아래 소스와 같이 
수정합니다.
ria.view.pgms.project.ProjectMgrPanel은 우리가 구현할 프로그램으로 사내 프로젝트를 심플하게 관리하는
프로그램입니다.
/**
 ** Date : 2012.11.30
 ** Desc : 시스템이하 프로그램 리스트 제공
 ** Posn : /json/programlist.json
 **/
{"entitys":[{"pgm_class":"ria.view.pgms.project.ProjectMgrPanel","pgm_icon":"grid","pgm_nm":"나의 과제","title":"나의 과제"},
            {"pgm_class":"ria.view.pgms.RiaAppMain02","pgm_icon":"grid","pgm_nm":"하위 프로그램2","title":"프로그램2"},
            {"pgm_class":"ria.view.pgms.RiaAppMain03","pgm_icon":"grid","pgm_nm":"하위 프로그램3","title":"커뮤니케이션팀"},
            {"pgm_class":"ria.view.pgms.RiaAppMain04","pgm_icon":"grid","pgm_nm":"하위 프로그램4","title":"커뮤니케이션팀"},
            {"pgm_class":"ria.view.pgms.RiaAppMain05","pgm_icon":"grid","pgm_nm":"하위 프로그램5","title":"커뮤니케이션팀"},
            {"pgm_class":"ria.view.pgms.RiaAppMain06","pgm_icon":"grid","pgm_nm":"하위 프로그램6","title":"커뮤니케이션팀"}
            ],
            "errMsg":"","errTitle":"검색결과","message":"","success":true,"totalCount":"2"}



// ria.view.pgms.project.ProjectMgrPanel 구현 하기.
Ext.define('ria.view.pgms.project.ProjectMgrPanel',{
    extend : 'Ext.panel.Panel',
    alias : 'widget.ProjectMgrPanel',
    layout : 'border',
    initComponent: function() {
        var me = this;
        this.callParent(arguments);
    }
});

이제 실행해보면 아래와 같은 모양의 프로그램이 우측 패널에 보여지게 된다.

공통적으로 도움말, MyPage,로그아웃, 검색 등의 기능을 사용할 수 있는 구조이다.

각각의 기능은 나중에 구현하도록 하고 “나의과제”라는 프로그램을 구현해봅니다.

이 프로그램은 좌측에 그리드패널을 그 그리드의 데이터를 select하면 우측의 폼패널이 열리고

해당 과제의 내용을 보여주도록 구현하겠습니다.

/**
 ** Date : 2012.11.30
 ** Desc : 프로젝트 리스트 제공
 ** Posn : /json/projectlist.json
 **/
{"entitys":[{"prj_master_no":"PJ000001","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000002","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000003","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000004","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000005","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000006","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000007","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"},
            {"prj_master_no":"PJ000008","ytree_sgy_dtl_seq":"001","prj_leader":"쥐박이","prj_name":"1원가절감을 위한 공수산정","prj_bgrnd":"추진배경은 .....","prj_target":"프로젝트목표","prj_effect":"프로젝트효과","prj_std_dt":"2012.01.10","prj_end_dt":"2012.12.10","prj_status_cd":"A","prj_status_nm":"결재중","input_user_name":"홍길동","input_date":"2012.01.29"}
            ],
            "errMsg":"","errTitle":"검색결과","message":"","success":true,"totalCount":"340"}
/**
 * Date : 2012.11.30
 * Desc : 프로젝트 정보를 표현할 모델 클래스
 */
Ext.define('ria.model.ProjectMaster', {
    extend: 'Ext.data.Model',   // extend
    fields: [
        'prj_master_no',
        'ytree_sgy_dtl_seq',
        'prj_leader',
        'prj_name',
        'prj_bgrnd',
        'prj_target',
        'prj_effect',
        'prj_status_cd',
        'prj_status_nm',
        'prj_std_dt',
        'prj_end_dt',
        'input_user_name',
        'input_user_id',
        'input_date'
    ]
});

/**
 * Date : 2012.12.14
 * Desc : 프로젝트 리스트
 */
Ext.define('ria.store.project.Projects', {
    extend: 'Ext.data.Store',   // 당연히 store상속
    autoLoad : false,           // 자동 로드는 꺼놓자.
    model: 'ria.model.ProjectMaster',   // 모델은 동일하게 사용 세팅
    proxy: {
        type: 'ajax',
        url: '/json/project/projectlist.json',  
        reader: {
            type: 'json',
            root: 'entitys',
            totalProperty: 'totalCount',
            messageProperty: 'message'
        },
        listeners: {
            exception: function(proxy, response, operation){
                // 나중에 구현할 부분 모든 ajax 통신에 공통으로 쓸 수 있는
                // 에러 캐치 함수를 만들 것이다.
            }
        }
    }
});

Ext.define('ria.view.pgms.project.ProjectListPanel',{
    extend : 'Ext.grid.Panel',
    alias  : 'widget.ProjectListPanel',
    columnLines: true,
    initComponent: function() {
        var me = this;
        var store = Ext.create('ria.store.project.Projects');
        Ext.apply(this, {
            store: store,
            columns: [
            {
                text: '과제번호',
                width : 80,
                dataIndex: 'prj_master_no'
            },
            {
                text: '제목',
                flex : 1,
                dataIndex: 'prj_name'
            },
            { 
                text: '작성자',
                width: 70,
                sortable: false,
                dataIndex: 'input_user_name'
            },
            { 
                text: '시작일',
                width: 70,
                sortable: false,
                dataIndex: 'prj_std_dt'
            },
            { 
                text: '종료일',
                width: 70,
                sortable: false,
                dataIndex: 'prj_end_dt'
            },
            { 
                text: '작성일',
                width: 70,
                sortable: false,
                dataIndex: 'input_date'
            }],
            dockedItems: [
            {
                xtype: 'pagingtoolbar',
                store: store,
                //name : 'fnc003Main01',
                dock: 'bottom',
                displayInfo: true
            }],
            boardLoad : function(){
                me.store.load({             // 아직 로드전이므로 로드한다.이때 json파일 호출
                    params : {
                        km : 'A00000001'
                    }
                });
                //console.log('me.store:::', me.store)
            }
        });
        me.callParent(arguments);
        this.on('render', this.boardLoad, this);
    }
});

Ext.define('ria.view.pgms.project.ProjectMgrPanel',{
        extend : 'Ext.panel.Panel',
        alias : 'widget.ProjectMgrPanel',
        layout : 'border',
        initComponent: function() {
                var me = this;
                Ext.apply(this, {
                        items : [{
                                xtype : 'ProjectListPanel',
                                title : '과제리스트',
                                region: 'center'
                        }]
                });
                this.callParent(arguments);
        }
});

이제 실행해 봅니다. 우측에 프로젝트 리스트 패널이 실행되고 json파일의 내용이 출력되는 것을
확인 할 수 있습니다.

Posted by 베니94
자바스크립트/Ext JS2012. 12. 12. 12:43

이제 어플리케이션의 틀이 완성되었으니 내용을 채울 차례입니다.

아래 그림은 앞으로 만들어볼 화면입니다.

"프로그램"탭에는 자신이 가지고 있는 권한내에서 필요한 프로그램이 보여지고

그 옆 "지식관리"라는 탭은 모두 공통적으로 사용하는 게시판성 프로그램입니다.

각각이 패널과 그리드, 상속관계, 레이아웃, 버튼, PropertyGrid 등의 요소를 포함하고 

있어 좋은 예제로 생각됩니다.

금주내로 아래 프로그램에 대해 강좌를 진행하도록 하겠습니다.


Posted by 베니94
자바스크립트/Ext JS2012. 12. 7. 13:23

이번에는 지금까지 코드를 정리 하는 시간을 좀 갖도록 하겠습니다. 실제 시스템을 ExtJS로 구축하도보면 

특히나 MVC모델로 구현할 경우 Controller가 비대해지는 현상이 발생합니다.


이는 MVC를 오해해서 생기는 현상이 아닌가 생각되는데요. MVC에서 V는 View를 의미하는데 이러한 이유로 

View안에는 기능적인 코드가 다 빠져있고 그 것들이 모두 Controller안에 들어가 있게 됩니다. 


Controller역할을 로직의 구현으로 이해하는 경우인것 입니다. 결과적으로 Controller안에 모든 관련 View의 기능이

 구현되어 있고 View는 껍데기만 존재하는 것이죠.


이렇게 비대해진 Controller는 유지보수 입장에서 굉장히 길고 파악하기 힘들게 되고 View자제의 재활용성이 

기능을 포함하지 않은 단순 껍데기만 재활용하게 되어 반쪽짜리 클래스로 전락하게 되는 것이죠.


제 생각이지만 이게 아니라 View은 일종의 클래스 (화면을 기준으로 화면제어 등의 기능이 포함된.)로 생각하고

UI와 그에 따른 제어기능도 포함되도록 해야합니다. 그래야만 재활용 측면에서도 해당 View Class를 가져다 쓸때

 기능도 함께 쓸 수 있게됩니다.


 기능이 모두 Controller에 구현될 경우 재활용은 Controller까지 신경써야하니 활용도가 떨어지게 되는 것입니다.


그래서 아래 코드는 View안에서는 자신과 관련된 기능에 대해 구현을 하고 Controller는 View에서 구현 된 

기능을 함수 단위로 호출 만 하도록 하게끔 리팩토링 작업을 한 것이니 참고하고 봐주시기 바랍니다.


아래 코드의 요점은 Controller에 구현된 로직을 각 뷰 클래스로 옮기고 Controller에서는 함수단위로 호출만

 하도록 변경한것입니다.


// 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({
    		// step1. 좌측 매뉴에 추가된 패널 즉 시스템 패널에 대한 이벤트 추가.
    		'WestMenuPanel > WestMenuDataViewPanel': {
    			afterrender: this.firstSelect,
    			expand: this.onItemClicked
            }
         });
    },
    /**
     *  step2. afterrender는 추가된 패널 별로 render된 이후에 호출한다.
     *	추가된 시스템 패널 중에 열려 있는지 확인하면 맨처음 하나만 열리게 된다.
     *	그 열려있는 시스템 패널에 하위 프로그램이 로딩되어 추가될 수 있도록 코딩해야한다.  
    **/
    firstSelect : function(panel){
    	panel.firstSelectDataView();
    },
    /**
     * Step3. 시스템 패널을 클릭 할 때 마다 expand이벤트가 호출 된다.
     * 이 때 클릭되어 expand된 패널 위에 하위 프로그램을 출력하면 된다.
     * @param a
     * @param b
     * @param c
     */
    onItemClicked : function(panel){
    	panel.onItemClicked();
    },
    onLaunch: function() {
        this.getWestMenu().setWestMenuDataViewPanel();
    }
});

// app/view/frame/WestMenuDataViewPanel.js 를 생성한다.
Ext.define('ria.view.frame.WestMenuDataViewPanel',{
    extend: 'Ext.panel.Panel',
    alias: 'widget.WestMenuDataViewPanel',
    animCollapse : true,
    collapsible : true,
    collapsed   : true,
    useArrows: true,
    rootVisible: false,
    multiSelect: false,
    initComponent: function() {
    	var me = this;
        Ext.apply(this, {
            items: [{
                xtype: 'dataview',
                trackOver: true,
                cls: 'feed-list',
                itemSelector: '.feed-list-item',
                overItemCls: 'feed-list-item-hover',
                tpl: '
{pgm_nm}

' }], header: { toolFirst: true }, /*** * Date : 2012.12.06 * Desc : dataview상에 출력된 리스트 중에 맨처음 프로그램이 * 선택되어지도록 한다. * @param store */ firstSelectDataView : function(){ if(me.collapsed) return; var store = this.onItemClicked(); if(store){ var task = new Ext.util.DelayedTask(function(){ me.down('dataview').getSelectionModel().select(store.getAt(0)); }); task.delay(1000); } }, /** * Step3. 시스템 패널을 클릭 할 때 마다 expand이벤트가 호출 된다. * 이 때 클릭되어 expand된 패널 위에 하위 프로그램을 출력하면 된다. * @param a * @param b * @param c */ onItemClicked : function(){ if(me.collapsed) return // 패널이 접히지 않은 놈을 찾는다. if(me.store) return; me.store = Ext.create('ria.store.system.Programs'); // 재활용 되는 것을 막는다. me.store.load({ params: { // 아래 코드는 시스템 패널이 가지고 있는 시스템 아이디를 프로그램 store에 전달하는 // 코드다 이렇게 해야 각기 시스템 패널별로 해당 시스템 이하의 프로그램을 가져올수 있다. pgm_syscd: this.pgm_syscd } }); // 최종 시스템 패널 안으 dataview에 프로그램 store를 바인딩 한다. me.down('dataview').bindStore(me.store); return me.store; } }); this.callParent(arguments); } }); // 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() { var me = this; Ext.apply(this, { /*** * Date : 2012.12.07 * Desc : 최초 첫번째 프로그램 선택. */ setWestMenuDataViewPanel: function(){ var store = Ext.create('ria.store.system.Systems'); store.load(function(record, b, c){ // 아직 로드전이므로 로드한다.이때 json파일 호출 store.each(function(rec){ // store를 탐색하여 me.add({ // 메뉴가 추가될 패널에 아래와 같이 패널을 추가. xtype:'WestMenuDataViewPanel', title:rec.get('pgm_sysnm'), // 시스템명 pgm_syscd:rec.get('pgm_syscd'), // 시스템 코드 iconCls:rec.get('pgm_sysicon') // 아이콘이 있다면 표기 }); }); }); } }); this.callParent(arguments); } });

이제 프로그램을 다시 확인해보면 동일하게 작동하는 것을 알수 있습니다. 앞으로는 Controller에 기능을 구현하고 구현된 기능을 어디로 옮겨야할지 생각해 본 후 각 뷰클래스등에 구현하므로해서 코드의 밸런스를 맞춰가도록 하겠습니다.


Posted by 베니94