@/utils/utils#MappingOberver JavaScript Examples

The following examples show how to use @/utils/utils#MappingOberver. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: row.js    From el-table-draggable with MIT License 4 votes vote down vote up
config = {
  WRAPPER,
  DRAGGABLE,
  /**
   * @param {Map<Element, Vue>} context
   * @param {Vue} elTableInstance
   * @param {number} animation
   * @returns {import('@types/sortablejs').SortableOptions}
   */
  OPTION(context, elTableInstance, animation) {
    const PROP = 'data'
    /**
     * 自动监听重建映射表
     */
    if (elTableInstance[DOM_MAPPING_NAME]) {
      elTableInstance[DOM_MAPPING_NAME].stop();
    }
    const mappingOberver = new MappingOberver(
      elTableInstance,
      WRAPPER,
    );

    elTableInstance[DOM_MAPPING_NAME] = mappingOberver;
    mappingOberver.rebuild();
    mappingOberver.start();
    let dommappingTimer = null
    let isTreeTable = checkIsTreeTable(elTableInstance) // 防止因为数据原因变化,所以每次选择都判断一次

    return {
      onChoose() {
        isTreeTable = checkIsTreeTable(elTableInstance)
        cleanUp()
        /**
         * 开始之前对所有表格做一定处理
         */
        for (const draggableTable of context.values()) {
          const domMapping = draggableTable[DOM_MAPPING_NAME];
          // 暂停dom监听,防止拖拽变化不停触发
          if (domMapping) {
            domMapping.stop();
          }

          if (isTreeTable) {
            addTreePlaceholderRows(
              domMapping.mapping,
              elTableInstance.treeProps,
              DRAGGABLE.replace('.', ''))
          }

          /**
           * 解决手动关闭后会有的错位问题
           * 导致原因,default-expanded-all
           * 需要记录一下当前打开的行,结束之后还原状态(待定)
           */
          draggableTable.store.states.defaultExpandAll = false;

          // 如果是空表格,增加一个css
          const tableEl = draggableTable.$el.querySelector(
            ".el-table__body-wrapper table"
          );
          if (tableEl.clientHeight === 0) {
            // body-wrapper增加样式,让overflw可显示同时table有个透明区域可拖动
            tableEl.parentNode.classList.add(EMPTY_FIX_CSS);
          }
        }
      },
      onStart(evt) {
        /**
         * expanded/树表格的处理, 关闭展开行
         */
        const { item } = evt;
        const domInfo = mappingOberver.mapping.get(item);
        // 收起拖动的行的已展开行
        dom.toggleExpansion(domInfo, false);
      },
      onMove(evt, originEvt) {
        const { related, dragged, to, from, willInsertAfter } = evt;
        const fromContext = context.get(from);
        const toContext = context.get(to);
        /** @type {DomInfo} */
        const draggedDomInfo =
          fromContext[DOM_MAPPING_NAME].mapping.get(dragged);
        /** @type {DomInfo} */
        const relatedDomInfo =
          toContext[DOM_MAPPING_NAME].mapping.get(related);

        /**
         * 树状表格的特殊处理,如果碰到的dom不是placeholder,则无视
         */
        if (isTreeTable) {
          if (relatedDomInfo.type !== 'placeholder') {
            return false
          }
        }

        /**
         * 判断是否需要修正当前dragged的对应level
         */
        // let targrtDomInfo = fixDomInfoByDirection(
        //   relatedDomInfo,
        //   draggedDomInfo,
        //   willInsertAfter
        // );
        let targrtDomInfo = relatedDomInfo

        const onMove = getOnMove(elTableInstance);
        if (onMove) {
          const onMoveResutl = onMove(evt, originEvt, {
            dragged: draggedDomInfo,
            related: targrtDomInfo,
          });

          /**
           * @todo 兼容willInserAfter属性
           */
          switch (onMoveResutl) {
            case 1: {
              if (!willInsertAfter) {
                targrtDomInfo = relatedDomInfo
                // fixDomInfoByDirection(
                //   relatedDomInfo,
                //   draggedDomInfo,
                //   true
                // );
              }
              break;
            }
            case -1: {
              if (willInsertAfter) {
                targrtDomInfo = relatedDomInfo
                // fixDomInfoByDirection(
                //   relatedDomInfo,
                //   draggedDomInfo,
                //   false
                // );
              }
              break;
            }
            case false: {
              return false;
            }
            default: {
              break;
            }
          }
        }

        /**
         * relatedDomInfo,自动将children插入到自身后方
         * @todo 需要增加动画效果,目标直接插入,需要在下一循环,位置变化好后再配置
         */
        setTimeout(() => {
          /** @type {import('types/DomInfo').DomInfo} */
          relatedDomInfo.childrenList.forEach((children) => {
            // expanded或者是影子行
            if (children.type === "proxy") {
              dom.insertAfter(children.el, relatedDomInfo.el);
            }
          });
        });

        const {
          states: { indent },
        } = fromContext.store;
        dom.changeDomInfoLevel(draggedDomInfo, targrtDomInfo.level, indent);
      },
      onEnd(evt) {
        const { to, from, pullMode, newIndex, item, oldIndex } = evt;
        const fromContext = context.get(from);
        const toContext = context.get(to);

        /** @type {DomInfo} */
        const fromDomInfo = fromContext[DOM_MAPPING_NAME].mapping.get(item);
        /**
         * @type {DomInfo[]}
         * 之前目标位置的dom元素, 因为dom已经换了,所以需要通过elIndex的方式重新找回来
         */
        const toDomInfoList = Array.from(
          toContext[DOM_MAPPING_NAME].mapping.values()
        );
        const toDomInfo =
          toDomInfoList.find((domInfo) => domInfo.elIndex === newIndex) ||
          toContext[DOM_MAPPING_NAME].mapping.get(to);
        // const toDomInfo = {
        //   ...fixDomInfoByDirection(
        //     originToDomInfo,
        //     fromDomInfo,
        //     from === to ? newIndex > oldIndex : false
        //   ),
        // };

        // 跨表格index修正
        if (
          from !== to &&
          to.querySelectorAll(DRAGGABLE).length <= 2
        ) {
          toDomInfo.index = newIndex;
        }

        /**
         * 数据层面的交换
         */
        // mapping层面的交换
        exchange(
          fromDomInfo.index,
          fromDomInfo.parent.childrenList,
          toDomInfo.index,
          toDomInfo.type === "root"
            ? toDomInfo.childrenList
            : toDomInfo.parent.childrenList,
          pullMode
        );

        // 数据层面的交换
        exchange(
          fromDomInfo.index,
          fromDomInfo.data,
          toDomInfo.index,
          toDomInfo.data,
          pullMode
        );

        // clone对象的话,需要从dom层面删除,防止el-table重复渲染
        if (pullMode === 'clone' && from !== to) {
          to.removeChild(fromDomInfo.el)
        }

        // 通知更新
        updateElTableInstance(from, to, context, function (tableContext) {
          const draggableContext = tableContext.$parent; // 包裹组件
          const data = tableContext[PROP];
          draggableContext.$emit("input", data);
        });

        /**
         * dom修正,因为exchange之后el-table可能会错乱,所以需要修正位置
         * 将原始的dom信息带回来children带回来
         * 删除一些临时加进去的行
         */
        // 根据mapping自动重新绘制, 最高一层就不用rebuild了
        if (toDomInfo.parent && toDomInfo.parent.parent) {
          dom.toggleExpansion(toDomInfo.parent, true);
        }
        // expanded部分
        dom.toggleExpansion(fromDomInfo, true);
        /** @todo 缓存是否强制expanded */
        toContext.toggleRowExpansion(fromDomInfo.data, true);

        cleanUp()
      },
      onUnchoose() {
        cleanUp()
        /**
         * 全局重新开始监听dom变化
         * 需要在之前dom操作完成之后进行
         */
        if (dommappingTimer) {
          clearTimeout(dommappingTimer)
        }
        dommappingTimer = setTimeout(() => {
          for (const draggableTable of context.values()) {
            const domMapping = draggableTable[DOM_MAPPING_NAME];
            if (domMapping) {
              domMapping.rebuild();
              domMapping.start();
            }
          }
        }, 100);
      },
    };
  },
}