我有一个父Angular 组件,它使用ngFor指令显示子组件。每个子组件都充当父组件中的一个单独窗口,它们的位置可以通过CdkDrag重新排列。我还在右上角创建了一个小“X”按钮来关闭子组件。当我点击“x”按钮关闭一个索引较低的子组件时,(例如,下面stackbliz示例中的1或2),其他子窗口将自动重新排列。是否有方法阻止这种重新排列,并在关闭任何子窗口时保持原样?
子组件
@Input('target') target: string = '';
@Input('index') index: string = '';
@Output() onClose: EventEmitter<number> = new EventEmitter();
closeModal() {
const i: number = +this.index;
this.onClose.emit(i);
}
字符串
子模板
<div class="example-box" cdkDrag>
{{target}}
<button class="CloseButton" (click)="closeModal()">X</button>
</div>
型
子CSS
.example-box {
width: 100px;
height: 100px;
border: solid 1px #ccc;
color: rgba(0, 0, 0, 0.87);
display: flex;
justify-content: center;
position: relative;
resize: both;
}
.CloseButton {
position: absolute;
top: 10px;
right: 10px;
}
型
父组件
names: string[] = ['1', '2', '3'];
modalClosed(id: any) {
this.names.splice(id, 1);
console.log(id);
}
型
父模板
<div class="ParentMain">
<child-comp
*ngFor="let name of names ; index as i"
(onClose)="modalClosed($event)"
target="{{name}}"
index="{{i}}"
>
</child-comp>
</div>
型
父CSS
.ParentMain {
display: flex;
}
型
完整的stackbliz示例
4条答案
按热度按时间col17t5w1#
还有另一种方法,我记得在这个SO中使用过,
如果我们想象一个cdkDropList里面有“items”,我们可以做一些类似的事情,
字符串
是的,cdkDropList与列表不同!
型
还有一些.css
型
Stackblitz
vhmi4jdf2#
当cdk拖动时,将样式更改为添加transform的元素:3D。这就是为什么如果更改“origin”(您将元素放置在带有flex的div中),则元素会排列在另一个位置。
如果使用endDrag事件给予一个绝对位置和左上角位置,则可以避免这种情况。但在此之前,将“cdkDrag”改为chuid中的div,您可以拖动整个元素
字符串
在子组件中,我们将在构造函数中执行elementRef注入
型
嗯,像这样的拖拽
型
由于你使用的是一个非常老的cdk-drag版本,你在事件中没有“位置”,所以我们需要在启动drag时做一些工作
型
最后是使“ Package 器”在所有元素被拖动时转换宽度和高度
型
A stackblitz
2nc8po8w3#
它属于拖放时如何处理项目位置,需要在onDragEnded事件后保存项目位置,可以看示例here:
z3yyvxxp4#
如果你想在关闭按钮被按下后保留每个对话框的位置,那么有很多方法可以做到这一点。最简单的方法是在按钮被点击时隐藏对话框,而不是将它们从模板中删除。
这里有一个这样做的例子:https://stackblitz.com/edit/angular-pqf4je-aatkjg?file=src%2Fapp%2Fchild-comp.html
在上面的例子中,点击对话框会导致项目消失,但其余的项目不应该移动,因为项目实际上仍然存在,它只是被设置为不透明度:0。
一个稍微先进一点的方法,不会导致屏幕上有很多不可见的组件,那就是使用CSS将项目定位在特定的位置-这样当一个被删除时,它们就不会移动。