5

我正在使用 Dragula 在我的桌子上拖放。此外,我正在使用插件 angular resizier 元素来调整表格列的大小。所有这些我一直在 Angular2 中工作。

所以我想要的是这个。我目前的情况就像图像上的这个灰色列。整个列宽是可拖动的,这让我在调整列大小时遇到​​了问题。因此,当我尝试调整列的大小时,它就像拖放一样。我希望我的柱子像这个黄色的柱子。有一些调整大小的空间。

这里是我的html代码的一部分:

<div class="row" [dragula]='"one-bag"' [dragulaModel]='names'>
    <div class="col" *ngFor="let name of names"
         mwlResizable
         [validateResize]="validate"
         [resizeEdges]="{right: true}"
         [enableGhostResize]="false">
         <label>{{name}}</label>
    </div>  
</div>

这是我一直在使用的调整器。 https://github.com/mattlewis92/angular-resizable-element

问题:如何在同一个表列上使用 ng2-dragula 和调整大小?

4

2 回答 2

1

I've been having the same problem myself, but with ngDraggable instead of dragula...

Only solution i have thought of is to set Handlers for both, like mwlResizeableHandler HTMLElement for the resizeable module and another for the ngDraggable module, stop propagation of click events on both and force them to update the same Style object within the Component, which is then passed with ngStyle on to the element to determine its position on the browser.

I think that the source of the problem is the fact that ngDraggable implements a transformation : translate(x,y) while resizeable refers to an Styles Object, meaning top/left positioning.

I haven't implemented the solution yet, but once i configure it in code i will post an update.

EDIT/UPDATE:

okay, what i did was implement my own draggable functions, which proved easier on the long run. this is my resizable:

<div @fade id="{{index}}" class="box" [ngStyle]="style"
    mwlResizable 
    [validateResize]="validate"
    [resizeCursorPrecision]="resizeCursor"
    [enableGhostResize]="true"
    [ghostElementPositioning]="style.position"
    (resizeEnd)="onResizeEnd($event)"
    (click)="setSelected($event)"
    [ngClass]="{selected : selected}">
    <div 
    style="cursor: move; height: 50px; width: 50px; border: 2px solid black; background-color: green;"
    (mousedown)="onMouseDown($event)" 
    (mousemove)="onMove($event)"
    (mouseup)="finalPosition($event)"
    (mouseleave)="finalPosition($event)">
    </div>
    <img class="resize-handle-top-left" 
    mwlResizeHandle  
    [resizeEdges]="{top: true, left: true}"
    src="http://i.imgur.com/eqzz2dl.gif">
    <img class="resize-handle-top-right" 
    mwlResizeHandle  
    [resizeEdges]="{top: true, right: true}"
    src="http://i.imgur.com/eqzz2dl.gif">
    <img class="resize-handle-bottom-left" 
    mwlResizeHandle  
    [resizeEdges]="{bottom: true, left: true}"
    src="http://i.imgur.com/eqzz2dl.gif">
    <img class="resize-handle-bottom-right" 
    mwlResizeHandle  
    [resizeEdges]="{bottom: true, right: true}"
    src="http://i.imgur.com/eqzz2dl.gif">
  </div>
</div>

code that implements the resizing:

public onResizeEnd(event: ResizeEvent): void {
      this.style = {
      position: 'absolute',
      left: `${event.rectangle.left}px`,
      right: `${event.rectangle.right}px`,
      top: `${event.rectangle.top}px`,
      bottom: `${event.rectangle.bottom}px`,
      width: `${event.rectangle.width}px`,
      height: `${event.rectangle.height}px`
    };

so what i did was just a temporary box in the middle of the div and set some event listeners on it, mousedown, mousemove, mouseup. The checkBoundaries functions are just there to check that the drag does not exceed the parents DIV limitations:

checkBoundariesLeft(styleAttr: number, tempMove: number): number {
    if ((styleAttr + tempMove) > 0 && (styleAttr + tempMove) < (this.api.imageW - Number.parseInt(this.style.width))) {
      this.previousLeft = (styleAttr + tempMove);
      return this.previousLeft;
    }
    return this.previousLeft;
  }
  checkBoundariesRight(styleAttr: number, tempMove: number): number {
    if ((styleAttr + tempMove) > Number.parseInt(this.style.width) && (styleAttr + tempMove) < this.api.imageW) {
      this.previousRight = (styleAttr + tempMove);
      return this.previousRight;
    }
    return this.previousRight;
  }

  checkBoundariesTop(styleAttr: number, tempMove: number): number {
    if ((styleAttr + tempMove) > 0 && (styleAttr + tempMove) < (this.api.imageH - Number.parseInt(this.style.height))) {
      this.previousTop = (styleAttr + tempMove);
      return this.previousTop;
    }
    return this.previousTop;
  }

  checkBoundariesBottom(styleAttr: number, tempMove: number): number {
    if ((styleAttr + tempMove) > Number.parseInt(this.style.height) && (styleAttr + tempMove) < this.api.imageH) {
      this.previousBottom = (styleAttr + tempMove);
      return this.previousBottom;
    }
    return this.previousBottom;
  }

  public onMouseDown(event: MouseEvent): void {
    event.stopPropagation();
    this.moveElementInitiated = true;
    this.tempCoords = {
      left : event.offsetX,
      top : event.offsetY
    };
  }

  public onMove(event: MouseEvent): void {
    if (this.moveElementInitiated) {
      const tempLeft = (event.offsetX - this.tempCoords.left) / this.ratio;
      const tempTop = (event.offsetY - this.tempCoords.top) / this.ratio;
      this.style = {
        position: 'absolute',
        left: `${this.checkBoundariesLeft(Number.parseInt(this.style.left), tempLeft)}px`,
        right: `${this.checkBoundariesRight(Number.parseInt(this.style.right), tempLeft)}px`,
        top: `${this.checkBoundariesTop(Number.parseInt(this.style.top), tempTop)}px`,
        bottom: `${this.checkBoundariesBottom(Number.parseInt(this.style.bottom), tempTop)}px`,
        width: this.style.width,
        height: this.style.height
      };
    }
  }

  public finalPosition(event): void {
    this.moveElementInitiated = false;
  }

I should note that all functions Update the same style object within the component.

于 2018-02-23T09:32:01.220 回答
0

您可以使用 move 方法仅允许从某个区域拖动,如下所示:

constructor(private dragulaService: DragulaService) {
this.dragulaService.createGroup("CARDS", {
  direction: "vertical",
  moves: (el, source, handle): boolean => handle.className.indexOf("ri-card-header") > -1
});
}

这样你就可以指定一个 CSS 选择器来决定是否允许移动。如果moves 方法返回false,那么事件将被转发并且移动不会开始。

于 2021-08-12T15:42:39.527 回答