mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(drag-utils): add utility function for cloning array items from one array to another (#13743)
* feat(drag-utils): add utility function for cloning array items from one array to another creates a utility helper for cloning an array item into the array of the drop container compliments moveItemInArray and transferArrayItem partially closes #13100 * feat(drag-utils): add utility function for cloning array items from one array to another resolves issues surfaced from code review * feat(drag-utils): add utility function for cloning array items from one array to another cuts extra space between parens * removes link in comments, and clarifies function definition as recommended in review * resolves nits
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import {moveItemInArray, transferArrayItem} from './drag-utils';
|
||||
import {moveItemInArray, transferArrayItem, copyArrayItem} from './drag-utils';
|
||||
|
||||
describe('dragging utilities', () => {
|
||||
describe('moveItemInArray', () => {
|
||||
@@ -66,4 +66,45 @@ describe('dragging utilities', () => {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('copyArrayItem', () => {
|
||||
it('should be able to copy an item from one array to another', () => {
|
||||
const a = [0, 1, 2];
|
||||
const b = [3, 4, 5];
|
||||
|
||||
copyArrayItem(a, b, 1, 2);
|
||||
expect(a).toEqual([0, 1, 2 ]);
|
||||
expect(b).toEqual([3, 4, 1, 5]);
|
||||
});
|
||||
|
||||
it('should handle an index greater than the target array length', () => {
|
||||
const a = [0, 1, 2];
|
||||
const b = [3, 4, 5];
|
||||
|
||||
copyArrayItem(a, b, 0, 7);
|
||||
|
||||
expect(a).toEqual([0, 1, 2]);
|
||||
expect(b).toEqual([3, 4, 5, 0]);
|
||||
});
|
||||
|
||||
it('should handle an index less than zero', () => {
|
||||
const a = [0, 1, 2];
|
||||
const b = [3, 4, 5];
|
||||
|
||||
copyArrayItem(a, b, 2, -1);
|
||||
expect(a).toEqual([0, 1, 2]);
|
||||
expect(b).toEqual([2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
it('should not do anything if the source array is empty', () => {
|
||||
const a: number[] = [];
|
||||
const b = [3, 4, 5];
|
||||
|
||||
copyArrayItem(a, b, 0, 0);
|
||||
expect(a).toEqual([]);
|
||||
expect(b).toEqual([3, 4, 5]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -42,7 +42,6 @@ export function transferArrayItem<T = any>(currentArray: T[],
|
||||
targetArray: T[],
|
||||
currentIndex: number,
|
||||
targetIndex: number): void {
|
||||
|
||||
const from = clamp(currentIndex, currentArray.length - 1);
|
||||
const to = clamp(targetIndex, targetArray.length);
|
||||
|
||||
@@ -51,6 +50,26 @@ export function transferArrayItem<T = any>(currentArray: T[],
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies an item from one array to another, leaving it in its
|
||||
* original position in current array.
|
||||
* @param currentArray Array from which to copy the item.
|
||||
* @param targetArray Array into which is copy the item.
|
||||
* @param currentIndex Index of the item in its current array.
|
||||
* @param targetIndex Index at which to insert the item.
|
||||
*
|
||||
*/
|
||||
export function copyArrayItem<T = any>(currentArray: T[],
|
||||
targetArray: T[],
|
||||
currentIndex: number,
|
||||
targetIndex: number): void {
|
||||
const to = clamp(targetIndex, targetArray.length);
|
||||
|
||||
if (currentArray.length) {
|
||||
targetArray.splice(to, 0, currentArray[currentIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Clamps a number between zero and a maximum. */
|
||||
function clamp(value: number, max: number): number {
|
||||
return Math.max(0, Math.min(max, value));
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<div>
|
||||
<div class="demo-list">
|
||||
|
||||
<h2>To do</h2>
|
||||
<mat-slide-toggle color="primary" [(ngModel)]="cloneMode">
|
||||
Clone Mode
|
||||
</mat-slide-toggle>
|
||||
<div
|
||||
cdkDropList
|
||||
#one="cdkDropList"
|
||||
|
||||
@@ -9,7 +9,12 @@
|
||||
import {Component, ViewEncapsulation} from '@angular/core';
|
||||
import {MatIconRegistry} from '@angular/material/icon';
|
||||
import {DomSanitizer} from '@angular/platform-browser';
|
||||
import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';
|
||||
import {
|
||||
CdkDragDrop,
|
||||
moveItemInArray,
|
||||
transferArrayItem,
|
||||
copyArrayItem
|
||||
} from '@angular/cdk/drag-drop';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
@@ -19,6 +24,8 @@ import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
export class DragAndDropDemo {
|
||||
|
||||
cloneMode = false;
|
||||
axisLock: 'x' | 'y';
|
||||
todo = [
|
||||
'Go out for Lunch',
|
||||
@@ -56,10 +63,19 @@ export class DragAndDropDemo {
|
||||
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);
|
||||
if (this.cloneMode) {
|
||||
copyArrayItem(
|
||||
event.previousContainer.data,
|
||||
event.container.data,
|
||||
event.previousIndex,
|
||||
event.currentIndex);
|
||||
} else {
|
||||
transferArrayItem(
|
||||
event.previousContainer.data,
|
||||
event.container.data,
|
||||
event.previousIndex,
|
||||
event.currentIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user