[ExtJs] 拖動 變更元素位置

實現一個,左邊是導航信息,右側是展示區域,然後拖動 導航節點重新定位後,右側也隨之j進行佈局變化,如下圖:

核心方法:

ExtJS容器對象.move(fromIdx,toIdx)

因爲涉及的知識點較多,後期有空補上,先貼上核心思想:

生成節點

右側的容器元素,首先就是根據左側的樹形展開結構,依次渲染的,也就是將多維的樹,看成一個導航。

將多維的數組,平鋪爲一個一維數組

根據這個數組,進行依次加載各類控件。

移動的節點 

尋找移動的位置後,他的前一個節點(注意不是同級前一個 而是 樹形展開後前一個)這是爲了定移動目標,知道移動到誰的屁股後面

  /*
        尋找上一個樹形文件節點
    */
    findPreNode(node) {
        const me = this;
        if(!node) return null;
        let preNode = node.previousSibling;
        if(preNode) {
            if(preNode.isLeaf() && preNode.get('LineType')!='L') //文件節點
            {
                return preNode;
            }else { //文件夾節點
                if(preNode.hasChildNodes()) {
                  return  me.findLastNode(preNode.lastChild);
                } else return me.findPreNode(preNode);
            }
        }else {
            if(node.get('ParentID')=='Root') {
                return null;
            }
            return me.findPreNode(node.parentNode);//必須加return 以用於層層接收值
            //否則就得用 me.findPreNode(node.parentNode, targetNode) 用targetNode 做傳遞參數
        }
    },

 再找到移動節點的子孩子,之所以找第一個子孩子,就是爲了要他的起始位置,在一維數組裏,變更了元素位置,後面的元素下標也都跟隨變化了,所以我們只要找第一個要移動的節點的位置即可。

//尋找第一個非文件夾節點
    findFirstNode(node) {
        const me = this;
        if(node.isLeaf()) {
            if(node.get('LineType')!='L')//非文件夾節點
            return node;
            else return null;
        }
        else if(node.hasChildNodes()) {
            node.eachChild(function (child) {
              return me.findFirstNode(child);
            });
        }
    }

找齊了上面的信息,就可以得到fromIdx,和toIdx了 

     //節點移動
    nodeMove(node) {
        const me = this,
        content = me.down('#content');//訪問右側展示容器
        let prenode = me.findPreNode(node);//當前位置現在的前一個元素
        let toIdx = 0, //目標位置
        firstChild = me.findFirstNode(node),
        fromIdx = content.indexOf(me.down(`#${firstChild.getId()}`)); //起始位置
        if(prenode) {
            toIdx = content.indexOf(me.down(`#${prenode.getId()}`));//上面元素的位置
            if(toIdx < fromIdx) toIdx = toIdx + 1;//向上挪到位置加1
        }
        me.moveItem(content, fromIdx, toIdx, node);
    },

然後再借助遞歸,進行逐級依序地進行移動

 moveItem(container, fromIdx, toIdx, node) {
        const me = this;
        if(node.isLeaf()) {
            if(node.get('LineType') !='L')//非文件夾節點 執行 移動
            container.move(fromIdx, toIdx);
        }else if(node.hasChildNodes()) {
            node.eachChild(function (child) {
                return me.moveItem(container, fromIdx, toIdx, child);
            });
        }
    },

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章