Angular5拖拽排序时移除选中元素active类的问题求助
解决Angular拖拽时移除选中项active类的问题
你的问题在于之前用@ViewChild("myLabel")只能获取到第一个匹配的<li>元素,所以拖拽时只有第一个元素的active类被移除,其他选中的项没变化。而且直接操作DOM并不是Angular推荐的做法,我们可以通过状态绑定来更优雅地解决这个问题。
方案一:通过拖拽状态控制active类显示
这种方式利用Angular的属性绑定,在拖拽过程中暂时隐藏所有选中项的active样式,拖拽结束后自动恢复,完全符合Angular的响应式思路。
修改TypeScript代码:
首先添加一个dragging状态变量,用来标记是否处于拖拽状态,然后监听dragula的拖拽开始和结束事件来更新这个状态:
import {Component, OnInit} from '@angular/core'; import { DragulaService } from 'ng2-dragula'; export class SummaryComponent implements OnInit { // 初始化必要的数组(你原来的代码里可能漏了这部分) selectedQuestions: any[] = []; questions: any[] = []; // 新增拖拽状态标记 dragging = false; constructor(private dragula: DragulaService){ } ngOnInit() { // 拖拽开始时设置dragging为true this.dragula.drag.subscribe(value => { this.dragging = true; console.log("拖拽开始"); }); // 拖拽结束(无论是否放下)时恢复状态 this.dragula.dragend.subscribe(value => { this.dragging = false; console.log("拖拽结束"); }); } addThisQuestionToArray(person: any, i: number, event) { if (!event.ctrlKey) { this.selectedQuestions = []; } this.toggleItemInArr(this.selectedQuestions, person); } toggleItemInArr(arr, item) { const index = arr.indexOf(item); index === -1 ? arr.push(item) : arr.splice(index, 1); } isQuestionSelected(question: any) { return (this.selectedQuestions.indexOf(question) !== -1); } }
修改HTML模板:
在[class.active]的判断条件里加上&& !dragging,这样拖拽时dragging为true,所有选中项的active类都会被移除:
<li class="well dragbox" *ngFor="let question of questions; let i = index" [attr.data-id]="question.QuestionId" [attr.data-index]="i" (click)="addThisQuestionToArray(question,i, $event)" [class.active]="isQuestionSelected(question) && !dragging" > {{i}} {{question.QuestionId}} {{question.Question}} </li>
方案二:直接操作所有选中元素(不推荐)
如果你一定要通过DOM操作来实现,可以用@ViewChildren获取所有带#myLabel的元素,然后遍历移除active类。但这种方式需要在拖拽结束后重新添加选中项的active类,相对繁琐:
修改TypeScript代码:
import {Component, OnInit, ViewChildren, QueryList, ElementRef} from '@angular/core'; import { DragulaService } from 'ng2-dragula'; export class SummaryComponent implements OnInit { selectedQuestions: any[] = []; questions: any[] = []; // 获取所有myLabel元素 @ViewChildren("myLabel") labels: QueryList<ElementRef>; constructor(private dragula: DragulaService){ } ngOnInit() { this.dragula.drag.subscribe(value => { console.log("拖拽开始"); // 遍历所有元素移除active类 this.labels.forEach(label => { label.nativeElement.classList.remove("active"); }); }); this.dragula.dragend.subscribe(value => { console.log("拖拽结束"); // 拖拽结束后,重新为选中的问题添加active类 this.labels.forEach(label => { const questionId = label.nativeElement.dataset.id; const matchedQuestion = this.questions.find(q => q.QuestionId == questionId); if (this.isQuestionSelected(matchedQuestion)) { label.nativeElement.classList.add("active"); } }); }); } // 其他方法和之前一样... }
总结
推荐使用方案一,它更符合Angular的响应式编程理念,不需要手动操作DOM,代码更简洁易维护,也避免了DOM操作可能带来的各种问题。
内容的提问来源于stack exchange,提问作者Rosa Mystica
相关产品推荐
相关产品推荐

