javascript - 为什么在使用 Angular Material 时,我拖入下拉列表的元素会丢失顶部和左侧 CSS 属性?
问题描述
在过去的 3 天里,我正在学习 Angular Material Drag And Drop,并尝试使用 Angular Material 将对象/元素拖放到 10x10 矩阵中。
在找到这个 andswer和这个 stackblitz之后,我试图将它应用到我的需求和概念中。我必须修复一些错误,更改样式、数组等。
这是我的堆栈闪电战。我非常接近完成它,但是有两个错误我无法弄清楚如何修复它们,并且我在上面的示例中找不到任何解决方案:
在这个我已经工作了大约 24 小时。将一艘船部署到板上并部署后,当您在板上移动同一艘船时,将其移动到不同的行和列时没有问题。但是当你将它移动到与之前相同的列时,
app-ship
元素(ShipComponent
的选择器)失去了 CSSleft
属性。当你将它移动到同一行时,它会失去 CSStop
属性,并且在视觉上被放置在矩阵的边缘,与left
prop 一样。拖入同一列的示例: 我完全不知道为什么它会丢失这些属性。第二个错误,我还没有处理,但也许你现在会有一些想法,发生在你已经在游戏板上部署了 2 艘或更多艘船时,首先你正在移动一艘船,然后是另一艘,而不是另一艘船将移至第一个,第二个将移至左上角,缺少
left
和top
CSS 属性。
这两个问题很有可能是相互关联的。
组件.ts:
import { Component, ElementRef, ViewChild } from "@angular/core";
import {
CdkDragDrop,
moveItemInArray,
transferArrayItem,
} from "@angular/cdk/drag-drop";
import { ShipComponent } from "./ship.component";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"],
})
//https://stackblitz.com/edit/angular-salbpl?file=src%2Fapp%2Fapp.component.html
export class AppComponent {
public list1: Array<ShipComponent>;
public list2: Array<ShipComponent>;
public boardP1: number[][];
public position: any;
constructor() {
this.boardP1 = this.getEmptyBoard();
this.list1 = this.createFleet();
this.list2 = [];
}
@ViewChild("two", { read: ElementRef, static: false }) boardElement: any;
@ViewChild("ships", { read: ElementRef, static: false }) shipsElement: any;
onDrop(event: CdkDragDrop<Array<ShipComponent>>) {
console.clear();
console.log(this.position);
event.previousContainer.data[event.previousIndex].top =
this.position.y -
this.boardElement.nativeElement.getBoundingClientRect().y;
event.previousContainer.data[event.previousIndex].left =
this.position.x -
this.boardElement.nativeElement.getBoundingClientRect().x;
if (event.previousContainer === event.container) {
moveItemInArray(
event.container.data,
event.previousIndex,
event.currentIndex
);
} else {
transferArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex
);
}
console.log("t: " + event.container.data[event.previousIndex].top);
console.log("l: " + event.container.data[event.previousIndex].left);
console.log("s: " + event.container.data[event.previousIndex].size);
if (this.shipsElement.nativeElement) {
console.log("top: " + this.shipsElement.nativeElement.style.top);
console.log("left: " + this.shipsElement.nativeElement.style.left);
}
}
private createFleet(): Array<ShipComponent> {
return [
{ size: 4, rotate: false, top: 0, left: 0 },
{ size: 3, rotate: false, top: 0, left: 0 },
{ size: 3, rotate: false, top: 0, left: 0 },
{ size: 2, rotate: false, top: 0, left: 0 },
{ size: 2, rotate: false, top: 0, left: 0 },
{ size: 2, rotate: false, top: 0, left: 0 },
{ size: 1, rotate: false, top: 0, left: 0 },
{ size: 1, rotate: false, top: 0, left: 0 },
{ size: 1, rotate: false, top: 0, left: 0 },
{ size: 1, rotate: false, top: 0, left: 0 },
];
}
private getEmptyBoard(): number[][] {
return Array.from({ length: 10 }, () => Array(10).fill(0));
}
}
组件.html:
<div class="container">
<div class="ships">
<h2>Available ships: {{ this.list1.length }}</h2>
<div
class="droplist"
cdkDropList
#one="cdkDropList"
[cdkDropListData]="list1"
[cdkDropListConnectedTo]="[two]"
(cdkDropListDropped)="onDrop($event)"
cdkDropListSortingDisabled="true"
>
Next:
<ng-container *ngIf="list1.length > 0">
<div cdkDrag [style.size]="50 * list1[0].size + 'px'">
<app-ship [size]="list1[0].size"></app-ship>
</div>
</ng-container>
</div>
</div>
</div>
<div class="example-boundary">
<div
class="droplist"
cdkDropList
#two="cdkDropList"
[cdkDropListData]="list2"
[cdkDropListConnectedTo]="[one]"
(cdkDropListDropped)="onDrop($event)"
cdkDropListSortingDisabled="true"
>
<ng-container *ngFor="let ship of list2">
<app-ship
#ships
[size]="ship.size"
cdkDrag
[style.top.px]="ship.top"
[style.left.px]="ship.left"
>
</app-ship>
</ng-container>
<div class="board">
<div class="row" *ngFor="let row of boardP1">
<div class="cell" *ngFor="let box of row" id="columns">
<button
#bt
mat-button
class="bt-cell"
(mouseover)="position = bt.getBoundingClientRect()"
></button>
</div>
</div>
</div>
</div>
</div>
解决方案
这个提到的例子可以在线工作,但在我的本地机器上不能正常工作,可能是因为 Angular 8 版本,而我使用的是 10+。我也找不到修复错误的方法。我决定重新构建我的示例项目,并更好地控制我的组件中通过Material Drag and Drop完成的事情。
最后,在工作解决方案中,我决定摆脱CdkDragDrop
事件,moveItemInArray
对transferArrayItem
数组和对象进行手动操作。现在我只使用: cdkDrag
, cdkDragStarted
, cdkDragEnded
,cdkDragMoved
事件。
这是我的解决方案的版本,其中修复了提到的错误。
推荐阅读
- oracle - 如何从列中提取时间并从 Oracle 中的自定义时间中减去
- javascript - 如何使用 Express js 保护简单的 GET 请求
- java - 我试图计算一些字符串的 hashCode 但失败了,我做错了什么?
- javascript - 在包括 $get (jQuery) 的 for 循环中填充一个数组 - i 没有增加
- javascript - 如何在 JavaScript 中重复一个字符串数组,让我得到它的总和?
- swift - 如何在 Swift 中解决“二叉树的最低共同祖先”?
- vim - 如何将当前寄存器的内容放入 vimscript 中的新缓冲区?
- r - 获得 R 中多个模型系数的函数的置信区间
- javascript - 为什么在输入时分离 d3 方法链会改变结果?
- ios - CoreData 多线程获取在访问属性之前需要很小的延迟