Angular 带有(反应式)表单的 CDK 拖放
Angular CDK drag drop with (reactive) forms
我有这个例子:https://stackblitz.com/edit/angular-asevei?file=app%2Fcdk-drag-drop-sorting-example.html
一切正常,但是 while 拖动 选择框 'resets' 到列表中的第一个值。
有什么办法可以解决这个问题吗?它只是视觉上的,但对用户来说非常刺耳。我试过使用 cdkDragPreview
选项,但无法正常工作。
分量:
import { Component } from '@angular/core';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
@Component({
selector: 'cdk-drag-drop-sorting-example',
templateUrl: 'cdk-drag-drop-sorting-example.html',
styleUrls: ['cdk-drag-drop-sorting-example.css'],
})
export class CdkDragDropSortingExample {
myForm: FormGroup;
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
title: ['title'],
items: fb.array([
fb.group({
name: fb.control('1'),
note: fb.control('quux')
}),
fb.group({
name: fb.control('2'),
note: fb.control('bar')
}),
fb.group({
name: fb.control('3'),
note: fb.control('baz')
})
])
})
}
drop(event: CdkDragDrop<string[]>) {
moveItemInArray(this.myForm.get('items').controls, event.previousIndex, event.currentIndex);
moveItemInArray(this.myForm.get('items').value, event.previousIndex, event.currentIndex);
}
}
模板:
<form [formGroup]="myForm">
<input formControlName="title" />
<div cdkDropList id="foo" class="example-list" (cdkDropListDropped)="drop($event)">
<div class="example-box" *ngFor="let item of myForm.get('items').controls" cdkDrag>
<span cdkDragHandle>drag</span>
<div [formGroup]="item">
<input type="text" formControlName="name">
<select formControlName="note">
<option>foo</option>
<option>bar</option>
<option>baz</option>
<option>quux</option>
</select>
</div>
</div>
</div>
{{ myForm.value | json }}
</form>
你的代码没问题,但如果这样称呼它,这个问题是由 drag-drop cdk
引起的,因为据我所知,这是默认行为,但你可以解决问题以增强该行为以使其看起来不错给用户。
试试这个
<div class="example-box" *ngFor="let item of myForm.get('items').controls" cdkDrag #elem="cdkDrag">
<span cdkDragHandle>drag</span>
<div [formGroup]="item">
<input type="text" formControlName="name">
<select formControlName="note">
<option [hidden]="elem.moved">dragging...</option>
<option>foo</option>
<option>bar</option>
<option>baz</option>
<option>quux</option>
</select>
</div>
</div>
这里发生的事情 #elem="cdkDrag"
添加到拖动元素作为 local reference
和 <option [hidden]="elem.moved">dragging...</option>
当用户拖动元素时这里会发生什么 dragging select option
将在 select input
中显示,当用户结束拖动时它将再次隐藏并且 select 输入值将再次设置一些 css 它看起来不错。
我修改了@Amir Fawzy 的回答,添加了一个变量来获取拖动所选框时显示的当前活动笔记。
TS:
activeNote: string;
enter(i) {
this.activeNote = this.myForm.get('items')['controls'][i].get('note').value;
}
HTML:
<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
<div [id]="i" class="example-box" *ngFor="let item of myForm.get('items').controls; let i=index;" cdkDrag #elem="cdkDrag" (mouseenter)="enter(i)">
<span cdkDragHandle>drag</span>
<div [formGroup]="item">
<input type="text" formControlName="name">
<select formControlName="note">
<option [hidden]="elem.moved">{{activeNote}}</option>
<option>foo</option>
<option>bar</option>
<option>baz</option>
<option>quux</option>
</select>
</div>
</div>
</div>
似乎 Angular Material 中的 mat-select
工作正常,参见 https://ngfelixl.github.io/ng-libraries
我有这个例子:https://stackblitz.com/edit/angular-asevei?file=app%2Fcdk-drag-drop-sorting-example.html
一切正常,但是 while 拖动 选择框 'resets' 到列表中的第一个值。
有什么办法可以解决这个问题吗?它只是视觉上的,但对用户来说非常刺耳。我试过使用 cdkDragPreview
选项,但无法正常工作。
分量:
import { Component } from '@angular/core';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
@Component({
selector: 'cdk-drag-drop-sorting-example',
templateUrl: 'cdk-drag-drop-sorting-example.html',
styleUrls: ['cdk-drag-drop-sorting-example.css'],
})
export class CdkDragDropSortingExample {
myForm: FormGroup;
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
title: ['title'],
items: fb.array([
fb.group({
name: fb.control('1'),
note: fb.control('quux')
}),
fb.group({
name: fb.control('2'),
note: fb.control('bar')
}),
fb.group({
name: fb.control('3'),
note: fb.control('baz')
})
])
})
}
drop(event: CdkDragDrop<string[]>) {
moveItemInArray(this.myForm.get('items').controls, event.previousIndex, event.currentIndex);
moveItemInArray(this.myForm.get('items').value, event.previousIndex, event.currentIndex);
}
}
模板:
<form [formGroup]="myForm">
<input formControlName="title" />
<div cdkDropList id="foo" class="example-list" (cdkDropListDropped)="drop($event)">
<div class="example-box" *ngFor="let item of myForm.get('items').controls" cdkDrag>
<span cdkDragHandle>drag</span>
<div [formGroup]="item">
<input type="text" formControlName="name">
<select formControlName="note">
<option>foo</option>
<option>bar</option>
<option>baz</option>
<option>quux</option>
</select>
</div>
</div>
</div>
{{ myForm.value | json }}
</form>
你的代码没问题,但如果这样称呼它,这个问题是由 drag-drop cdk
引起的,因为据我所知,这是默认行为,但你可以解决问题以增强该行为以使其看起来不错给用户。
试试这个
<div class="example-box" *ngFor="let item of myForm.get('items').controls" cdkDrag #elem="cdkDrag">
<span cdkDragHandle>drag</span>
<div [formGroup]="item">
<input type="text" formControlName="name">
<select formControlName="note">
<option [hidden]="elem.moved">dragging...</option>
<option>foo</option>
<option>bar</option>
<option>baz</option>
<option>quux</option>
</select>
</div>
</div>
这里发生的事情 #elem="cdkDrag"
添加到拖动元素作为 local reference
和 <option [hidden]="elem.moved">dragging...</option>
当用户拖动元素时这里会发生什么 dragging select option
将在 select input
中显示,当用户结束拖动时它将再次隐藏并且 select 输入值将再次设置一些 css 它看起来不错。
我修改了@Amir Fawzy 的回答,添加了一个变量来获取拖动所选框时显示的当前活动笔记。
TS:
activeNote: string;
enter(i) {
this.activeNote = this.myForm.get('items')['controls'][i].get('note').value;
}
HTML:
<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
<div [id]="i" class="example-box" *ngFor="let item of myForm.get('items').controls; let i=index;" cdkDrag #elem="cdkDrag" (mouseenter)="enter(i)">
<span cdkDragHandle>drag</span>
<div [formGroup]="item">
<input type="text" formControlName="name">
<select formControlName="note">
<option [hidden]="elem.moved">{{activeNote}}</option>
<option>foo</option>
<option>bar</option>
<option>baz</option>
<option>quux</option>
</select>
</div>
</div>
</div>
似乎 Angular Material 中的 mat-select
工作正常,参见 https://ngfelixl.github.io/ng-libraries