如何将数组项目传输到另一个数组并使用Angular Material Drag N Drow CDK更新它,而不会两个项



我正在使用Angular Material Drag N Drow CDK将一组默认项目(列表1)移至动态项目列表(列表2)。当我将默认项目(L1)拖动到动态项目(L2),然后更新现在的动态项目(新的L2项目)时,它还更新了默认项目(旧L1项)。

当您将默认项目(L1)拖动到动态项目(L2)时,默认列表(L1)使用RESETELST方法将其重置回其原始数组。我的目标是将现在动态的项目(新的L2项目)更新,并可能将相同的默认项目(已重置的旧L1项目)拖动到动态列表(L2)中,创建另一个新的动态项目(另一个新的L2项目)。遇到的问题是,当我将默认项目(L1)拖到动态列表(L2)中时,然后更新新的动态项目(使用ngmodel的新L2项目)拖动并重置的默认项目(旧L1项)也更新。

这是我的html in form.component.html

<!-- Default Answer List - List 1 -->
 <aside cdkDropList id="defaultAnswerList"
            [cdkDropListConnectedTo]="['dynamicAnswerList']" [cdkDropListData]="defaultAnswers">
            <div class="aside-container">
                <div class="auto-complete-content-area p-10">
                    <div *ngFor="let answer of defaultAnswers">
                        <!-- answer.isInput - Text Input -->
                        <div class="element-wrapper addon-group" *ngIf="answer.isInput" cdkDrag>
                            <div class="label-side">
                                Short Text
                            </div>
                            <div class="element-side">
                                <input type="text" [(ngModel)]="answer.placeholderText" class="input-element"
                                    placeholder="Placeholder" />
                                <label>Drag to add a short text answer</label>
                            </div>
                        </div>
          </div>
       </div>
    </aside>
<!-- Dynamic Answer List - List 2-->
<div class="input-answers" cdkDropList id="dynamicAnswerList"
                    (cdkDropListDropped)="dropIt($event)" [cdkDropListData]="dynamicAnswers">
                        <div class="input-section" cdkDragLockAxis="y" style="cursor: all-scroll" *ngFor="let answer of dynamicAnswers; index as i"
                            cdkDrag>
                            <div class="input-wrapper" *ngIf="answer.isInput || answer.isAddressSearch || answer.isAgeInput || answer.isVehicleVIN">
                                <input type="text" class="input-box normal-input-box" [(ngModel)]="answer.placeholderText"
                                    placeholder="Add Text Placeholder" />
                            </div>
                        </div>
                    </div>

这是我的form.component.ts文件

// Here is the original array which is then set to defaultAnswers
defaultAnswersOrigin: Answer[] = [
        {isInput: true, placeholderText: "Enter Placeholder", hasPrefix: false, hasSuffix: false, prefixText: "", suffixText: "", width: "45", position: 0},
        {isDatePicker: true, placeholderText: "Enter Date Placeholder", hasPrefix: false, hasSuffix: false, prefixText: "", suffixText: "", width: "45", position: 1},
        {isSelect: true, placeholderText: "Enter Menu Placeholder", hasPrefix: false, hasSuffix: false, prefixText: "", suffixText: "", width: "45", position: 2},
        {isTextarea: true, secondaryPlaceholderText: "Enter Text Placeholder", hasSecondaryPlaceholder: true, hasPrefix: false, hasSuffix: false, prefixText: "", suffixText: "", width: "45", position: 3},
        {isCheckbox: true, displayValue: "", hasPrefix: false, hasSuffix: false, prefixText: "", suffixText: "", width: "45", position: 4},
        {isButton: true, placeholderText: "", hasPrefix: false, hasSuffix: false, prefixText: "", suffixText: "", displayValue: "Enter Button Text", width: "45", position: 5},
        {isPrevNextButtons: true, placeholderText: "", hasPrefix: false, hasSuffix: false, prefixText: "", suffixText: "", displayValue: "", width: "90", position: 6},
        {isProgressButton: true, placeholderText: "", hasPrefix: false, hasSuffix: false, prefixText: "", suffixText: "", displayValue: "", width: "90", position: 7}
    ];
 defaultAnswers = this.defaultAnswersOrigin;
 answers: Answers = [];
   // Drop it method used in html
    dropIt(event: CdkDragDrop<string[]>) {
        if (event.previousContainer !== event.container) {
            transferArrayItem(this.defaultAnswers,
                                 this.answers,
                                 event.previousIndex,
                                 event.currentIndex);
                this.answers.forEach((answer, i) => {
                    answer.position = i;
                });
            this.resetList();
        } else if (event.previousIndex !== event.currentIndex) {
            if (event.previousContainer === event.container) {
                moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
            }
        }
      }
// Reset list method used
     resetList() {
        this.defaultAnswers = [];
        setTimeout(() => {
          this.defaultAnswers = this.defaultAnswersOrigin.slice();
        }, 0);    
      }

我希望能够将项目从L1拖到L2并使用NGMODEL成功更新。在这个特定的用例中,我想更改占位符,这是答案类中的参数。

实际发生的事情是,从L1和L2的新项目都更新,就像它们绑定到同一参数一样。因此,如果不更改L1,我无法从L2更新项目。如果我还将同一项目从L1再次添加到L2中(我可以这样做,因为列表是重置的),则所有三个项目(L1,L2 New和2nd L2 New)将使用NGMODEL进行更新。

*******更新 - 复制stackblitz我能够重现Stackblitz中的错误。您可能需要刷新页面才能使拖动n滴来工作。

Steps to reproduce: 
1. go to url below
2. Drag a Short Text item from Default List into Dynamic List
3. Start changing the new items placeholder in Dynamic List
4. Notice how placeholder in reset Default list is changing as well
5. Add same item from Default list to Dynamic list again
6. Change placeholder of new item
7. Notice how all three placeholders change now
https://stackblitz.com/edit/cdk-drag-and-drop-q7qqvo

您需要创建原始项目的副本,然后将副本添加到第二个列表中。有很多复制对象的方法,但基本上是这样的:

function createCopy(orig){
   return  JSON.parse(JSON.stringify(orig))
}

替换

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

drop(event: any) {
    if (event.previousContainer === event.container) {
        moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    } else {
        copyArrayItem(event.previousContainer.data,
            event.container.data,
            event.previousIndex,
            event.currentIndex);
    }
}

请确认在哪里调用此功能复制数组&gt;

最新更新