如何限制拖放容器仅接受 Angular Material Drag-Drop Feature 中的一项 [英] How to limit drag - drop container to accept only one item in Angular Material Drag-Drop Feature

查看:17
本文介绍了如何限制拖放容器仅接受 Angular Material Drag-Drop Feature 中的一项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当使用@angular/cdk/drag-drop 模块(Angular Material Drag and Drop)时......有没有办法限制放置容器,以便只接受一个值而不是多个值?我正在尝试创建表单,用户可以将图像拖放到应该只有一个项目的字段中.我正在使用标准示例代码来实现 Drag and Drop |Angular Material 但找不到可以限制放置项目数量的解决方案,第二个无法找到保持拖动列表相同的解决方案(拖动的项目将保留在拖动容器中),因此您复制而不是将项目移动到放置容器.是否有任何解决方案或可以帮助示例代码的人?

HTML:

 

<h2>待办事项</h2>

<div class="example-box" *ngFor="let item of todo" cdkDrag>{{item}}</div>

<div class="example-container"><h2>完成</h2>

<div class="example-box" *ngFor="let item of done" cdkDrag>{{item}}</div>

TS:

import {Component} from '@angular/core';从'@angular/cdk/drag-drop'导入{CdkDragDrop,moveItemInArray,transferArrayItem};/*** @title 拖放连接排序*/@成分({选择器:'cdk-drag-drop-connected-sorting-example',templateUrl: 'cdk-drag-drop-connected-sorting-example.html',styleUrls: ['cdk-drag-drop-connected-sorting-example.css'],})导出类 CdkDragDropConnectedSortingExample {待办事项 = ['开始工作','拿起杂货','回家','睡着'];完成 = ['起床','刷牙','洗个淋浴','查看电子邮件',《遛狗》];drop(事件:CdkDragDrop){if (event.previousContainer === event.container) {moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);} 别的 {transferArrayItem(event.previousContainer.data,event.container.data,event.previousIndex,event.currentIndex);}}}

解决方案

这里有一个 工作演示 允许覆盖的我的版本.

确保您的屏幕足够宽,您可以看到两列.


你应该使用 cdkDropListEnterPredicate

如果您的目的地空位"已经填满,只需从这里返回 false.

请注意,您的处理程序是从 this 不是您的组件的上下文中调用的.所以你需要在你的组件中使用这样的 lambda 函数.

destinationNotEmptyPredicate = () =>{返回 this.destinationArray.length == 0;};

确保目的地列表的高度可以让您真正将东西放入其中.

但是,如果您需要允许覆盖假列表"中现有的单个项目(您可能会这样做),那么这就有点棘手了.您不会想要使用此谓词(因为它会阻止您删除任何内容,除非您先删除现有项目).

因此,在这种情况下,您需要进行 css 调整以隐藏已经存在的项目(当您将鼠标悬停在它上面时).

#even 是目的地列表.

#even.cdk-drop-list-dragging .cdk-drag:not(.cdk-drag-placeholder) {显示:无;}

同时设置 [cdkDropListSortingDisabled]=false" 以避免出现奇怪的动画故障.

当您删除"项目时,您的目的地列表应该只包含一个项目:

drop(event: CdkDragDrop) {if (event.previousContainer === event.container) {moveItemInArray(event.container.data,event.previousIndex,事件.currentIndex);} 别的 {this.even = [event.item.data];}}

注意我在这里仍然使用 cdkDropListEnterPredicate 来只允许删除偶数.

When using @angular/cdk/drag-drop module (Angular Material Drag and Drop)... Is there any way to limit drop container so to accept only one value instead of multiple values? I am trying to create form where user can drag image and drop into field which should have only one item. I am using standard example code for implementation from Drag and Drop | Angular Material but cannot find solution where number of dropped items can be limited, and second cannot find solution to keep Drag list the same (dragged item will stay in drag container) so you copy instead of move item to Drop container. Is there any solution or someone who can help with sample code?

HTML:

    <div class="example-container">
  <h2>To do</h2>

  <div
    cdkDropList
    #todoList="cdkDropList"
    [cdkDropListData]="todo"
    [cdkDropListConnectedTo]="[doneList]"
    class="example-list"
    (cdkDropListDropped)="drop($event)">
    <div class="example-box" *ngFor="let item of todo" cdkDrag>{{item}}</div>
  </div>
</div>

<div class="example-container">
  <h2>Done</h2>

  <div
    cdkDropList
    #doneList="cdkDropList"
    [cdkDropListData]="done"
    [cdkDropListConnectedTo]="[todoList]"
    class="example-list"
    (cdkDropListDropped)="drop($event)">
    <div class="example-box" *ngFor="let item of done" cdkDrag>{{item}}</div>
  </div>
</div>

TS:

import {Component} from '@angular/core';
import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';

/**
 * @title Drag&Drop connected sorting
 */
@Component({
  selector: 'cdk-drag-drop-connected-sorting-example',
  templateUrl: 'cdk-drag-drop-connected-sorting-example.html',
  styleUrls: ['cdk-drag-drop-connected-sorting-example.css'],
})
export class CdkDragDropConnectedSortingExample {
  todo = [
    'Get to work',
    'Pick up groceries',
    'Go home',
    'Fall asleep'
  ];

  done = [
    'Get up',
    'Brush teeth',
    'Take a shower',
    'Check e-mail',
    'Walk dog'
  ];

  drop(event: CdkDragDrop<string[]>) {
    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);
    }
  }
}

解决方案

Here's a working demo of my version that allows for overwriting.

Make sure your screen is wide enough you can see both columns.


You should use cdkDropListEnterPredicate

Just return false from this if your destination 'slot' is already filled.

Note that your handler is called from a context where this is not your component. So you need to use a lambda function like this in your component.

destinationNotEmptyPredicate = () => 
{
   return this.destinationArray.length == 0;
};

Make sure the destination list has a height such that you can actually drop something in it.

However if you need to allow overwriting of the existing single item in your 'fake list' (and you probably do) then it's a little trickier. You wouldn't want to use this predicate (because it would stop you from dropping anything unless you first deleted the existing item).

So in that case you need to do a css tweak to hide the item that already exists (when you hover over it).

#even is the destination list.

#even.cdk-drop-list-dragging .cdk-drag:not(.cdk-drag-placeholder) {
   display: none;
}

Also set [cdkDropListSortingDisabled]="false" to avoid a weird animation glitch.

When you 'drop' the item your destination list should be made to just contain one item:

drop(event: CdkDragDrop<number[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    } else {
      this.even = [event.item.data];
    }
  }

Notice how I'm still using the cdkDropListEnterPredicate here to allow only even numbers to be dropped.

这篇关于如何限制拖放容器仅接受 Angular Material Drag-Drop Feature 中的一项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆