키보드로 단추를 누르는 플러그인

10617 단어 ExtJSSencha
이 글은 Sencha Advent Calendar 2014 18일째 되는 글이다.
키보드로 버튼을 입력하다
나는 ExtJS의 플러그인을 만들어 보고 싶다.
필요조건
플러그인 요구 사항은 다음과 같습니다.
  • 기능키를 눌러 버튼
  • 을 클릭
  • 버튼과 버튼의 대응 자유 설정
  • 버튼을 클릭할 수 있는 조건에서만 (표시/활성화) 조작
  • 이루어지다
    간단하게 방법을 설명해 주세요.
    1. 플러그인 클래스 정의
    여느 때와 마찬가지로 Ext.define을 사용하여 반을 정의합니다.
    extend는 Ext.pluggin입니다.Abstract를 지정합니다.
    플러그인의 기본 클래스입니다.
    다음으로 제작된 플러그인 이름은 Btn Key Mapper입니다.
    Ext.define('Adventer.plugin.BtnKeyMapper', {
    
        // {{{ extend
    
        extend  : 'Ext.plugin.Abstract',
    
        // }}}
        // {{{ alias
    
        alias: 'plugin.btnkeymapper'
    
        // }}}
    
    });
    
    이렇게 되면 빈 플러그인은 아무것도 하지 않는다.
    저번 버튼을 만든 폼에 놓고 읽는다.
      /* Form.js */
    
        // {{{ tbar
    
        tbar: [
            {
                text: '保存',
                plugins: [{
                    ptype: 'btnkeymapper'
                }]
            }
        ],
    
        // }}}
    

    물론 아직 아무것도 변하지 않았다.
    다음은 정식 공연이다.
    2. init 방법 제작
    init 방법은 플러그인의 시작점입니다.
    pluggin의 구성 요소를 매개 변수로 설정합니다. (여기는client) 전달합니다.
    이거 client 어떻게든 해.
    참고로 init가 호출되는 시기는 구성 요소인 initComponent가 호출된 후입니다.렌더링하기 전에
    /* plugin.BtnKeyMapper.js*/
    
    // {{{ init
    
    init: function (client) {
        var me = this;
    
        console.log(clinent);
    },
    
    // }}}
    

    3. 어떤 키를 할당할까?
    이 설정은 버튼을 눌러서 설정한 것이다.
    우선 설정 파일을 플러그인에 전달할 것을 구상하십시오.
    /* Form.js*/
            {
                text: '保存',
                plugins: [{
                    ptype: 'btnkeymapper',
                    keyCode: Ext.event.Event.F1
                }]
            }
    
    플러그인 옆에 있는지 확인하십시오.
    접근법을 원하기 때문에 config에 넣고 구조기를 initConfig라고 합니다.
    /* plugin.BtnKeyMapper.js*/
    
    // {{{ config
    
    config: {
        keyCode: null
    },
    
    // }}}
    // {{{ constructor
    
    constructor: function (config) {
        this.callParent(config);
        this.initConfig(config);
    },
    
    // }}}
    // {{{ init
    
    init: function (client) {
        var me = this;
    
        console.log('KeyCode:' + me.getKeyCode());
    
    // }}}
    
    },
    

    무사하니, 우선 이 열쇠 번호의 움직임을 주워라.
    4. 열쇠 줍기 사건
    열쇠 줍기 이벤트 Ext.util.KeyMap을 사용하면 간단합니다.
    /* plugin.BtnKeyMapper.js*/
    
    // {{{ init
    
    init: function (client) {
        var me = this,
            keyCode = me.getKeyCode(),
            bind;
    
        bind = {
            target: document,
            key   : keyCode,
            fn    : me.doEmulate,
            defaultEventAction: 'stopEvent',
            scope : me
        };
    
        me.keyMap = new Ext.util.KeyMap(bind);
    
    },
    
    // }}}
    // {{{ doEmulate
    
    // キーイベントハンドラー
    doEmulate: function(keyCode, e) {
        var me = this;
    
        console.log('type : ' + keyCode);
    
    }
    
    // }}}
    
    Ext.util.키 이벤트와 호출 함수를 설정하기 위해 KeyMap에 구성 객체를 전달합니다.

    당분간 문서 전체의 이벤트를 주웠다.
    나는 잠시 후에 이 일대를 조정하고 싶다.
    5. 버튼 클릭
    실제로plugen은 cmp 속성에 설정된 구성 요소를 가지고 있습니다.
    그것에 대해 클릭하는 동작을 하면 된다.
    우선 클릭 이벤트 처리 프로그램을 준비합니다.
    ViewController에 적었어야 했는데 시도였기 때문에 View에 직접 적었습니다.
    /* Form.js*/
    
    {
        text: '保存',
        plugins: [{
            ptype: 'btnkeymapper',
            keyCode: Ext.event.Event.F1
        }],
        listeners: {
            'click': function(btn) {
                Ext.Msg.alert(
                    'イベント',
                    '保存ボタンがクリックされました!'
                );
            }
        }
    }
    
    그런 다음 플러그 인에서 클릭 이벤트로 변환합니다.
    /* plugin.BtnKeyMapper.js*/
    
    // {{{ doEmulate
    
    // キーイベントハンドラー
    doEmulate: function(keyCode, e) {
        var me = this,
            button = me.cmp;// ボタン
    
        button.fireEvent('click', button, e);
    
    }
    
    // }}}
    
    버튼 클릭/F1 키를 입력하면 이 내용을 표시할 수 있습니다.

    문제 발생:!
    /* Form.js*/
    
    {
        text: '保存',
        plugins: [{
            ptype: 'btnkeymapper',
            keyCode: Ext.event.Event.F1
        }],
        handler: function(btn) {
            Ext.Msg.alert(
                'イベント',
                '保存ボタンがクリックされました!'
            );
        }
    }
    
    이거 안 움직였어.
    수정된 오류!
    /* plugin.BtnKeyMapper.js*/
    
    // キーイベントハンドラー
    doEmulate: function(keyCode, e) {
        var me = this,
            button = me.cmp;// ボタン
    
        // TODO: 見た目変える
    
        // event発火/handler実行
        button.fireHandler(e);
    
    }
    
    // }}}
    
    FireHandler에서 클릭 활동을 하는 화재와handler의 호출.
    외관
    밀린 것처럼 보이면 무리예요.
    defer를 사용하여 반을 교체합니다.
    여기서 더 하고 싶은 게 있는데..
        // 見た目変える
        button.addCls('x-btn-pressed’);// 押された
    
        Ext.defer(function() {
            button.removeCls('x-btn-pressed’);// 離れた
        },300);
    
    여기까지
    요건 1과 요건 2가 명확한지 여부.
    6. 버튼 상태 점검
    버튼의 상태를 확인합니다.
    다음 두 가지를 확인하세요.
  • 표시 버튼
  • 버튼은 enable
  • DoEmulate 앞에서 확인합니다.
    1의 조건은 이 단추가 표시된 컨테이너가 있는지 확인해야 한다.
    어디까지 보일지 설정 가능한가요?
    parentQuery 구성에서 설정할 수 있습니다.
    /* Form.js*/
    
            {
                text: '保存',
                plugins: [{
                    ptype: 'btnkeymapper',
                    keyCode: Ext.event.Event.F1,
                    parentQuery: 'form'
                }],
                handler: function(btn) {
    
    플러그인은 조회에 따라 부모 용기의 상태를 확인합니다.
    /* plugin.BtnKeyMapper.js*/
    
    // {{{ config
    
    config: {
        keyCode: null,
        parentQuery: 'container'
    },
    
    // }}}
    …
    // {{{ doEmulate
    
    // キーイベントハンドラー
    doEmulate: function(keyCode, e) {
        var me = this,
            button = me.cmp;// ボタン
    
        if (!me.checkBtnEnable(button, keyCode, e)) {
            return false;
        }
    
        // 見た目変える
        button.addCls('x-btn-pressed');
    
        Ext.defer(function() {
            button.removeCls('x-btn-pressed');
        },300);
    
        // event発火/handler実行
        button.fireHandler(e);
    
    },
    
    // }}}
    // {{{ checkBtnEnable
    
    checkBtnEnable: function(button, keyCode, e) {
        var me              = this,
            parent          = button.up(me.getParentQuery()),
            parentIsVisible = true,
            clickable       = true;
    
        // 親コンテナーの状態チェック
        parentIsVisible = parent.isVisible();
    
        // 表示状態 かつ 活性状態であること
        clickable = parentIsVisible && button.isVisible() && !button.disabled;
    
        return clickable;
    }
    
    // }}}
    
    조건 3도 삭제!
    청소하다
    나는 많은 물건을 청소할 줄 안다.
    버튼이 폐기되면 이벤트 처리 프로그램도 폐기됩니다.
    다음은 모든 코드입니다.
    Ext.define('Adventer.plugin.BtnKeyMapper', {
    
        // {{{ extend
    
        extend  : 'Ext.plugin.Abstract',
    
        // }}}
        // {{{ alias
    
        alias: 'plugin.btnkeymapper',
    
        // }}}
        // {{{ mixins
    
        mixins: {
            observable: 'Ext.util.Observable'
        },
    
        // }}}
        // {{{ requires
    
        requires: [
            'Ext.util.KeyMap'
        ],
    
        // }}}
        // {{{ config
    
        config: {
            /**
            * @cfg {Number} keyCode
            * 監視するキーイベント
            * @accessor
            */
            keyCode: null,
    
            /**
            * @cfg {String} parentQuery
            * ボタンが表示状態かを確認する親コンテナ
            * @accessor
            */
            parentQuery: 'container'
        },
    
        // }}}
        // {{{ constructor
    
        constructor: function (config) {
            this.callParent(config);
            this.mixins.observable.constructor.call(this, config);
            this.initConfig(config);
        },
    
        // }}}
        // {{{ init
    
        init: function (client) {
            var me = this,
                bind;
    
            // ボタンがレンダリングされている間だけ実行するようにする
            me.mon(client, {
                destroy    : me.stopEmulation,
                afterrender: me.startEmulation,
                scope: me
            });
    
        },
    
        // }}}
        // {{{ startEmulation
    
        startEmulation: function(button) {
            var me = this,
                keyCode = me.getKeyCode(),
                bind   = {
                    target: document,
                    key   : keyCode,
                    fn    : me.doEmulate,
                    defaultEventAction: 'stopEvent',
                    scope : me
                };
    
            me.keyMap = new Ext.util.KeyMap(bind);
    
        },
    
        // }}}
        // {{{ stopEmulation
    
        stopEmulation: function(button) {
            var me = this;
            // keyイベント削除
            me.keyMap.destroy();
        },
    
        // }}}
        // {{{ doEmulate
    
        // キーイベントハンドラー
        doEmulate: function(keyCode, e) {
            var me = this,
                button = me.cmp;// ボタン
    
            if (!me.checkBtnEnable(button, keyCode, e)) {
                return false;
            }
    
            // 押されて
            button.addCls('x-btn-pressed');
            // 離す
            Ext.defer(function() {
                button.removeCls('x-btn-pressed');
            },300);
    
            // event発火/handler実行
            button.fireHandler(e);
    
        },
    
        // }}}
        // {{{ checkBtnEnable
    
        checkBtnEnable: function(button, keyCode, e) {
            var me              = this,
                parent          = button.up(me.getParentQuery()),
                parentIsVisible = true,
                clickable       = true;
    
            // 親コンテナーの状態チェック
            parentIsVisible = parent.isVisible();
            // 表示状態 かつ 活性状態であること
            clickable = parentIsVisible && button.isVisible() && !button.disabled;
    
            return clickable;
        }
    
        // }}}
    
    
    });
    
    총결산
    pluggin은 Ext.pluggin입니다.Abstract를 계승하여 제작합니다.plugen 내this에서cmp에 대해서 뭘 할 건지키 줍기 이벤트는 Ext.util입니다.KeyMap을 사용하면 간편합니다.제작 과정의 결과를 써서 오랜 시간을 낭비했다.반성하다.
    전선의 낭비도 많기 때문에 조정할 필요가 있으니 양해해 주십시오.
    내일은 Toshimitsusato씨입니다.

    좋은 웹페이지 즐겨찾기