本文介绍了将数组中的最后一个对象推到下一个数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个这样的对象:

container = {
    row1: [ '1', '2', '3', '4' ],
    row2: [ '5', '6', '7', '8' ],
    row3: [ '9', '10', '11', '12' ]
  }

此数据填充了我的Angular项目中的网格拖动n拖放组件.

This data populates a grid drag n drop component in my Angular project.

当一个项目"从一个数组移到另一个数组时,我希望该数组中的最后一个项目移至下一个数组,并将所有对象向前推1,这样我就可以确保其中只有4个对象每个数组.

When an 'item' is moved from one array to the other I would like the last item in that array to move to the next array and push all objects forward by 1 so that I can ensure there is only ever 4 objects in each array.

我该如何实现?我已经花了太多时间了!

How can I achieve this? I've been at it for way too many hours now!

我有这个'drop'方法,当将项目添加/放入新数组时会调用该方法:

I have this 'drop' method that is called when the item is added/dropped into a new array :

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);
    }
  }

所以我现在需要的是这样的东西:

So what I need now is something like :

this.container.data.unshift() //to the next array within the container array.

我也可以在组件中访问此数组,因此甚至可以传入行名:

I also have access to this array in my component so maybe even passing in the row name:

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

我该怎么做,如果需要的话,也可以将其反转.

How can I do this and it would also be nice to be able to reverse it if need be.

这是一个StackBlitz: https://stackblitz.com/edit/angular-cdk-drag-drop-cmyh7k?file=app%2Fcdk-drag-drop-connected-sorting-example.html

Here is a StackBlitz: https://stackblitz.com/edit/angular-cdk-drag-drop-cmyh7k?file=app%2Fcdk-drag-drop-connected-sorting-example.html

推荐答案

首先,您需要更新stackblitz的引用以获取Angular 8和cdk的新版本.还要删除pollyfill.ts中对core.js的引用.

First you need update the references of the stackblitz to get the new version of Angular 8 and cdk. Remove the references to core.js in pollyfill.ts too.

这使您可以在各行之间拖动

This make that you can drag among the rows

将放置功能"更改为例如

After change the "drop function" as, e.g.

drop(event: CdkDragDrop<string[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    } else {
      const dataFrom=event.previousContainer.data[event.previousIndex]
      const dataTo=event.container.data[event.currentIndex]
      event.previousContainer.data.splice(event.previousIndex,1,dataTo)
      event.container.data.splice(event.currentIndex,1,dataFrom)

    }
  }

您不必使用功能"transferArrayItem".您在event.previousContainer.data中具有数据,而在event.container.Data中具有数据,因此您可以使用拼接播放"从另一个元素中删除一个元素.

You needn't use obligatory the function "transferArrayItem". you has in event.previousContainer.data the data from and in event.container.Data the data to, so you can "play" using splice to remove one element from another.

在我的情况下,我使用indexex来互换位置,但是您可以按照自己的方式进行操作

In my case I use the indexex, to put interchange the positions, but you can make in the way you want

提示:有趣的是创建一个event.previousContainer.data,event.container.data,event.previousIndex和event.currentIndex的console.log()以查看这些值

Tip: it's interesting make a console.log() of event.previousContainer.data, event.container.data, event.previousIndex and event.currentIndex to see the values

这是您的分叉堆栈闪动

更新另一个功能

drop(event: CdkDragDrop<string[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    } else {
      //get the data we are dragging
      const dataFrom=event.previousContainer.data[event.previousIndex]
      //get the last element of the row where dropped
      const dataTo=event.container.data[event.container.data.length-1]

      //remove the element dragged
      event.previousContainer.data.splice(event.previousIndex,1)
      //Add at last the dataTo
      event.previousContainer.data.push(dataTo)

      //Add the data dragged
      event.container.data.splice(event.currentIndex,0,dataFrom)
      //remove the last element
      event.container.data.pop()

    }
  }

Update2 ,看起来有些陌生人",因此我们可以考虑是否使用(cdkDropListEntered)(cdkDropListExited)和(cdkDragStarted)可以改善效果.

Update2 it's looks like some "stanger", So we can think about if using (cdkDropListEntered) (cdkDropListExited) and (cdkDragStarted) we can improve a better effect.

这个想法是,如果我们重新排列该行或不拖拽任何内容,则在每行中添加一个元素,该元素将不可见(显示:无).如果我们在行之间拖动,则此元素将获取我们放置的行的最后一个元素的值.

The idea is add one element to each row that will be invisible (display:none) if we are reorden the row or we are not draggind anything. If we are dragging between rows, this element gets the value of the last element of the row where we are dropped.

吹气,首先声明三个变量

Puff, first declare three variables

  fade=[" "," "," "]   //to show the elements
  indexDrag:number=-1  //the row from we picked the element
  indexEnter:number=-1  //the row where we want dropped the element

我们要在拖动项之前添加div

After we are goind to add a div before the drag items

<div cdkDropList cdkDropListOrientation="horizontal"
  [cdkDropListData]="container.row1" class="example-list"
  (cdkDropListDropped)="drop($event)"
  (cdkDropListEntered)="enter($event,0)" > //<--for the second row will be enter($event,1)
                                           // and for the third row enter($event,2)
  <!-- our element before the drags elements -->
  <div class="example-box"
        [style.display]="(indexDrag!=0 ||
                          indexEnter==indexDrag ||
                          indexEnter<0)?'none':null">
    <div class="tile">
      <div class="tile-container">{{fade[0]}}</div>
    </div>
  </div>
  <!--our dragabbles elements -->
  <div class="example-box" *ngFor="let item of container.row1" cdkDrag
     (cdkDragStarted)="startDrag(0)"> //<--for the second row will be startDrag(1)
                                      //  and startDrag(2) for the third row
    <div class="tile">
      <div class="tile-container">{{item}}</div>
    </div>
  </div>

然后,只需添加两个功能

Then, just add the two functions

  startDrag(index) {
    this.indexDrag=index;
  }
  enter(event: CdkDragEnter<any>,index) {
    this.indexEnter=index;
    const data=event.container.data
    this.fade[this.indexDrag]=data[data.length-1]
  }

然后,在放置函数中,我们重新启动"变量indexDrag,indexEnter并淡入淡出

And, in drop function we "restart" the variables indexDrag,indexEnter and fade

  drop(event: CdkDragDrop<string[]>) {

    this.indexDrag = -1;
    this.indexEnter = -1;
    this.fade=[" "," "," "]
     ...rest of the code..
  }

新的stackblitz

好吧,这是有问题的,因为我们可以将鼠标拖动到行的las元素上,并且应用程序失败,对不起.所以我们需要做另外的改变

Well, there's a problem becaouse we can drag over the las element of a row and the app fails, sorry. So we need make another change

在放置函数中检查currentIndex是否等于data.length

In drop function check if the currentIndex is equal to data.length

    const currentIndex=(event.currentIndex==event.container.data.length)?
              event.container.data.length-1:event.currentIndex

在div中再创建一个* ngIf最后一个

In the div make another *ngIf is last

    <div class="tile" *ngIf="!last || indexEnter!=1 || indexEnter==indexDrag">
      <div class="tile-container">{{item}}</div>
    </div>

这篇关于将数组中的最后一个对象推到下一个数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 09:14