`
xiongmao3
  • 浏览: 42128 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

EXT.DD的drop操作,Target是同group中父子关系的子DropTarget时的处理

    博客分类:
  • Ext
阅读更多
-_-\\ ... 

标题很拗口,,而且JAVAEYE限制长度,, 不知道表述出本意没有,,

还原应用场景先:

    以EXTJS教程中关于DD的示例代码为例子。

    想通过DD,把A区域中的某个item拖放到B区域中,或者是B区域的子区域C中,B、C定义在同一个ddGroup中。定义代码如下:
            dropTarget1 = new Tutorial.dd.MyDropTarget('dd2-B', {
                ddGroup: 'group',
                overClass: 'dd-over'
            });
            dropTarget2 = new Tutorial.dd.MyDropTarget('dd2-C', {
                ddGroup: 'group',
                overClass: 'dd-over'
            });


    把item拖放到B区域(父)中,no问题,示例代码中已经实现了。
    把item拖放到C区域(子)中,问题来啦,notifyDrop方法被调用了2次!!
   
    初步想法是,mouseup事件冒泡啦,C区域(子)响应后,再冒泡到B区域(父),DD的事件处理机制处理了两次drop。

    再次测试 B的子区域多定义N个,重叠位置,notifyDrop方法则被调用N次...

    跟踪代码,通过调用堆栈,定位到 DDCore.js中 Ext.dd.DragDropMgr 对象的 fireEvents方法。相关代码如下:


                for (i in this.ids[sGroup]) {
                    var oDD = this.ids[sGroup][i];
                    if (! this.isTypeOfDD(oDD)) {
                        continue;
                    }

                    if (oDD.isTarget && !oDD.isLocked() && oDD != dc) {
                        if (this.isOverTarget(pt, oDD, this.mode)) {
                            // look for drop interactions
                            if (isDrop) {
                                dropEvts.push( oDD );
                            // look for drag enter and drag over interactions
                            } else {

                                // initial drag over: dragEnter fires
                                if (!oldOvers[oDD.id]) {
                                    enterEvts.push( oDD );
                                // subsequent drag overs: dragOver fires
                                } else {
                                    overEvts.push( oDD );
                                }

                                this.dragOvers[oDD.id] = oDD;
                            }
                        }
                    }
                }
。。。
                // fire drop events
                for (i=0, len=dropEvts.length; i<len; ++i) {
                    dc.b4DragDrop(e, dropEvts[i].id);
                    dc.onDragDrop(e, dropEvts[i].id);
                }
   

Ext 把group中定义的满足的target push 到dropEvts集合中,并循环调用 onDragDrop方法。 onDragDrop方法定义在DragSource.js文件中的Ext.dd.DragSource对象里。相关代码摘录如下:
    /**
     * An empty function by default, but provided so that you can perform a custom action before the dragged
     * item is dragged out of the target without dropping, and optionally cancel the onDragOut.
     * @param {Ext.dd.DragDrop} target The drop target
     * @param {Event} e The event object
     * @param {String} id The id of the dragged element
     * @return {Boolean} isValid True if the drag event is valid, else false to cancel
     */
    beforeDragOut : function(target, e, id){
        return true;
    },
    
    // private
    onDragDrop : function(e, id){
        var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
        if(this.beforeDragDrop(target, e, id) !== false){
            if(target.isNotifyTarget){
                if(target.notifyDrop(this, e, this.dragData)){ // valid drop?
                    this.onValidDrop(target, e, id);
                }else{
                    this.onInvalidDrop(target, e, id);
                }
            }else{
                this.onValidDrop(target, e, id);
            }
            
            if(this.afterDragDrop){
                /**
                 * An empty function by default, but provided so that you can perform a custom action
                 * after a valid drag drop has occurred by providing an implementation.
                 * @param {Ext.dd.DragDrop} target The drop target
                 * @param {Event} e The event object
                 * @param {String} id The id of the dropped element
                 * @method afterDragDrop
                 */
                this.afterDragDrop(target, e, id);
            }
        }
        delete this.cachedTarget;
    },

    /**
     * An empty function by default, but provided so that you can perform a custom action before the dragged
     * item is dropped onto the target and optionally cancel the onDragDrop.
     * @param {Ext.dd.DragDrop} target The drop target
     * @param {Event} e The event object
     * @param {String} id The id of the dragged element
     * @return {Boolean} isValid True if the drag drop event is valid, else false to cancel
     */
    beforeDragDrop : function(target, e, id){
        return true;
    },


target.notifyDrop 这里即是EXTJS示例文件中notifyDrop调用的源头,这里beforeDragDrop方法是一个空方法,始终返回true。

分析入参发现,e是event对象,当前fireEvent的对象是C区域(子),ID是遍历前面DropEvts集合依次传入的target的ID,于是决定把判断加在这个方法中以屏蔽B区域(父)对当前事件的响应。代码如下:
Ext.dd.DragSource.prototype.beforeDragDrop = function(target, e, id){

        if(e.getTarget().id == id)
            return true;
        else 
            return false;
}



----------------------------朴实的分割线----------------------------

在这种解决方案中,事件还是冒泡啦,只是通过判断dropEvts中的target是否是fireEvent的target而屏蔽notifyDrop方法的重复调用。

是否有更好的方式处理,希望达人不吝指教。

另,想重载Ext.dd.DargSource的beforeDragDrop方法时,发现这样做报错。。
Ext.extend(Ext.dd.DragSource,{
        beforeDragDrop : function(target, e, id){

        if(target.id==e.getTarget().id && target.id==id)
            return true;
        else 
            return false;
});


也希望达人不吝指教
0
2
分享到:
评论
1 楼 java365 2009-12-06  
看了楼主的问题,不过我属于ExtJS 的新手,对其应用还没达到楼主的水平。
只是我也遇到类似的问题,不过我的问题要更复杂些:
拖动源是一个 According 布局的几个GridPanel ,
而DropTarget 则是一个Panel中包含的一个TabPanel中的EditorGridPanel(可有多个相同Tab)

读了楼主的关于 屏蔽区域(父) 的解决方法,稍有点收获,如果楼主已经有了完备的关于这个议题的解决方法,希望楼主可以在blog中更新出来,我将关注。

相关推荐

    Ext Js权威指南(.zip.001

    Ex4.0共2个压缩包特性,《ext js权威指南》 前 言 第1章 ext js 4开发入门 / 1 1.1 学习ext js必需的基础知识 / 1 1.2 json概述 / 3 1.2.1 认识json / 3 1.2.2 json的结构 / 3 1.2.3 json的例子 / 4 1.2.4 ...

    iptables权威指南

    目录 译者序.................................................................................................................................................................................4 ...

    org.eclipse.swt.win32

    org.eclipse.swt.dnd.DropTarget.class org.eclipse.swt.dnd.DropTargetAdapter.class org.eclipse.swt.dnd.DropTargetEffect.class org.eclipse.swt.dnd.DropTargetEvent.class org.eclipse.swt.dnd....

    flash shiti

    20.Flash 菜单Modify→Group的快捷操作是? A. Ctrl+G B. Ctrl+Shift+G C. Ctrl+B D. Ctrl+Shift+P 21.Flash中如果想要测试完整的互动功能和动画功能怎么办? A. 选择 Control &gt; Loop Playback B. 选择 ...

    react-drag-drop-container:适用于鼠标和触摸设备的ReactJS拖放功能

    DragDropContainer和DropTarget 现场演示: 特征 非常容易实现和理解。 适用于鼠标和触摸设备。 拖动到边缘时自动滚动页面,因此可以拖动到最初不在屏幕上的目标。 可选的拖动手柄(带有dragHandleClassName )...

    flash action script 经典字典教程大全,学flash必备

    _target Button._target、MovieClip._target、TextField._target _totalframes MovieClip._totalframes _url Button._url、MovieClip._url、TextField._url _visible Button._visible、MovieClip._visible、...

    NSC_DropTarget

    IDropTarge的实现可以接受由其他程序拖放来的文本等详细见源代码和例子我对这个也不是很熟,写得不好,请大家赐教

    delphi资源-Treeview的使用介绍

    delphi中Treeview的使用介绍  每一个节点下子节点形成这一节点的Items属性,当前节点有一个唯一的Index(TreeNode的Index属性),用于...DropTarget属性表明节点在拖动操作中是源还是目标。 .1.添加、删除、修改节点:

    SWT JFace 拖曳效果

    演示代码如下: 代码如下:package swt_jface.demo11; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DragSource;... import org.eclipse.swt.dnd.Drop

    Java实现文字随意拖动.rar

    Java实现文字随意拖动,随处拖动文本字符,移动到任意位置,super("文本的拖动处理"); //调用父类构造函数  String[] data = {"one", "two", "three", "four"}; //字符数组,用于构造列表框  DragList list=new...

    flash拼图游戏

    if(eval(_root.tp14._droptarget)&lt;&gt;_root.fg14) { _root.tp14.startDrag(true); } } on (release) { stopDrag(); } x=getProperty(_root.tp14,_droptarget) if(x eq "/fg14") {setProperty(_root.tp14,...

    swing文件拖拽

    public void drop(DropTargetDropEvent e) { try { DataFlavor stringFlavor = DataFlavor.stringFlavor; Transferable tr = e.getTransferable(); TreePath path = this.getPathForLocation(e.getLocation()....

    react-dragndrop:简单的拖放插件

    该库带有2个React组件: 和&lt;DropTarget&gt; 。 为了使这两个组件能够相互通信,必须使用以下代码创建DragDropManager的实例: import {DragDropManager, Draggable, DropTarget} from 'react-dragndrop'let manager = ...

    skidder:拖放ClojureScript

    要安装,请将以下内容添加到您的项目中:dependencies : [g7s/skidder "0.1.0"] 文献资料 skidder是一个系统,您可以启动,停止和收听更改 ( ns test.app ( :require [skidder.core :as skidder])) ( skidder/...

    可重新排序的列表框:创建一个列表框,其内容可以通过单击和拖动项目进行重新排序。-matlab开发

    用户可以在输入属性/值对列表中指定他们自己的“MousePressedCallback”(JList)、“MouseReleasedCallback”(JList)、“DragOverCallback”(DropTarget)和“DropCallback”(DropTarget)。 这些回调将在 ...

    dragdrop拖拽对象的C++封装

    封装了DragSource和DropTarget两个类 可以实现基于Windows桌面程序间自定义对象的拖拽操作 附带了: 使用封装的dragdrop类的例子代码[dragdrop_demo] 捕获拖拽对象数据和剪贴板数据的程序及代码[ClipSpy]

    DropListener:对 Matlab 的拖放支持-matlab开发

    添加对 Matlab 的拖放支持(作为 java.awt.dnd.DropTarget 之上的代理) 源码存储在 GitHub 上,点击“了解更多”按钮进入项目页面。 该项目基于 Maarten van der Seijs 在文件交换方面的 dndcontrol 贡献。 它旨在...

Global site tag (gtag.js) - Google Analytics