如何在拖动,拖动预览和拖动占位符时自定义Angular material 7中的CSS?

时间:2019-04-18 17:19:23

标签: angular html5 drag-and-drop angular-material angular7

我找到了一些有关如何使用.cdk-drag-preview.cdk-drag-placeholder类的基本示例,当它们没有嵌套元素时,它们似乎可以发挥作用。

基本上,我有一个动作列表,每个动作都以复杂的mat-card格式表示。该部分实际上是作为另一个组件完成的,但是出于本示例的考虑,我将使其尽可能地基本。

我的示例类似于此结构:

<style>
    .my_action { border: 2px solid red; }
</style>

<div class="drop_area" cdkDropList>
    <div *ngFor="let action of actions"
        (cdkDragStarted)="dragStart($event, action)"
        (cdkDragMoved)="dragMoved($event, action)"
        (cdkDragEnded)="dragEnded($event, action)" cdkDrag>

        <mat-card class="my_action">
            {{ action.name }}
        </mat-card>

    </div>
</div>

在角度分量中

dragStart(e, action) { 
    // initialize start X coord
    this.startX = 0;

    // initialize start Y coord
    this.startY = 0;
}

dragMoved(e, action) {
    // record new position
    this.endX = e.pointerPosition.x;
    this.endY = e.pointerPosition.y;

    // logic to set startX and startY
    // TRYING TO CHANGE CARD BORDER COLOR IF this.endX - this.startX > some number
}

我希望能够执行以下操作:

  • 向左拖动卡片时,将其边框颜色更改为蓝色,向右拖动时将其边框颜色更改为绿色
  • 相应地更改拖动占位符的边框颜色。

使用.cdk-drag-preview.cdk-drag-placeholder的问题似乎适用于可拖动的divmat-card的父母);而我正在尝试更改其孩子的边框颜色。

预先感谢:)

添加

我最重要的挑战是更改拖动占位符的边框颜色。 我正在尝试更改占位符的边框颜色和左边距,以指示用户该操作已向左或向右移动,代表列表中的不同级别。

3 个答案:

答案 0 :(得分:1)

下面的内容可以实现您的目标吗?

初始化nativeElement x和y

dragStart(e, action) {
    const rect = e.source.element.nativeElement.getBoundingClientRect();

    // initialize start X coord
    this.startX = rect.x;
    // initialize start Y coord
    this.startY = rect.y;
  }

比较X偏移量,并使用rendere2nativeElement上设置样式

dragMoved(e, action) {
    // record new position
    this.currentX = e.event.clientX;
    this.currentY = e.event.clientY;
    // logic to set startX and startY
    // TRYING TO CHANGE CARD BORDER COLOR IF this.endX - this.startX > some number
    if(this.startX < this.currentX){
      this._renderer.setStyle(e.source.element.nativeElement, 'border-style', 'solid');
      this._renderer.setStyle(e.source.element.nativeElement, 'border-color', 'green');
    }
    else if (this.startX > this.currentX){
      this._renderer.setStyle(e.source.element.nativeElement, 'border-style', 'solid');
      this._renderer.setStyle(e.source.element.nativeElement, 'border-color', 'blue');
    }
  }

修订版:

要在拖动时更改颜色,请执行以下操作。

在视图中获取对#cdkDropList的引用。

@ViewChild('cdkDropList') _dropList:any;

*ngFor中设置索引

*ngFor="let action of actions; let i = index"

将索引传递给函数

(cdkDragMoved)="dragMoved($event, action, i)"

接收索引并进入cdkDropList的子级以设置样式。

dragMoved(e, action, i) {
    // record new position
    this.currentX = e.event.clientX;
    this.currentY = e.event.clientY;
    // logic to set startX and startY
    // TRYING TO CHANGE CARD BORDER COLOR IF this.endX - this.startX > some number
    if(this.startX < this.currentX){
      this._renderer.setStyle(this._dropList.nativeElement.children[i], 'border-style', 'solid');
      this._renderer.setStyle(this._dropList.nativeElement.children[i], 'border-color', 'green');
    }
    else if (this.startX > this.currentX){
      this._renderer.setStyle(this._dropList.nativeElement.children[i], 'border-style', 'solid');
       this._renderer.setStyle(this._dropList.nativeElement.children[i], 'border-color', 'blue');
    }
  }

Stackblitz

https://stackblitz.com/edit/angular-hdskvc?embed=1&file=app/cdk-drag-drop-overview-example.ts

答案 1 :(得分:1)

当一个 cdkDrag 元素被拾取时,它会在拖动时创建一个可见的预览元素。 这将是原始元素的克隆。 克隆的元素将删除其 id 属性并添加类 .cdk-drag-preview。

谨慎使用 cdkDragMoved,因为该事件将针对用户拖动的每个像素触发。

<div cdkDropList class="example-list">
    <div class="example-box" *ngFor="let action of actions" cdkDrag 
        (cdkDragStarted)="dragStart($event)"
        (cdkDragMoved)="dragMoved($event)">
        {{ action.name }}
    </div>
</div>

export class CustomComponent {
    cloned: any;

    actions = [
        { name: "one" },
        { name: "two" },
        { name: "three" }
    ];

    constructor(private _renderer: Renderer2) { }

    dragStart(event) {
        this.cloned = document.getElementsByClassName("cdk-drag-preview")[0];
    }

    dragMoved(event) {
        this._renderer.removeClass(this.cloned, "red");
        this._renderer.removeClass(this.cloned, "green");

        const distance: { x: number, y: number } = event.distance;
        this._renderer.addClass(this.cloned, (distance.x > 0) ? "green" : "red");
    }
}

答案 2 :(得分:0)

您可以这样做:

<div class="drop_area" cdkDropList>
<div *ngFor="let action of actions;let i = index;"
    (cdkDragStarted)="dragStart($event, action)"
    (cdkDragMoved)="dragMoved($event, action, i)"
    (cdkDragEnded)="dragEnded($event, action)" cdkDrag>

    <mat-card class="my_action{{i}}">
        {{ action.name }}
    </mat-card>

</div>

dragMoved(e, action, index: number) {
    // record new position
    this.endX = e.pointerPosition.x;
    this.endY = e.pointerPosition.y;

    // login to set startX and startY
    // TRYING TO CHANGE CARD BORDER COLOR IF this.endX - this.startX > some number

   document.getElementsByClassName('my_action'+index)[0].style.borderColor='blue';
}