使用 angular material 拖放时收音机输入选择会重置
Radio input selection resets when using angular material drag and drop
我正在尝试使用 angular material 拖放组件重新排序基本无线电输入列表。
页面加载时,会检查正确的无线电输入。我的问题是,当我使用 [Grab] 句柄对列表中选中的项目重新排序时,单选选项似乎重置了,我不知道如何保留该选择。
对我来说真正奇怪的是,如果这是一个复选框,它会工作得很好。所以我假设这与我设置无线电输入的方式有关。
感谢您提供的任何帮助。
这是我的 stackblitz:https://stackblitz.com/edit/angular-2q94xh
app.component.html
<table cdkDropList (cdkDropListDropped)="drop($event)">
<tr *ngFor="let selection of content" cdkDrag>
<td>
<div class="grab" cdkDragHandle>[Grab]</div>
</td>
<td>
<input
[id]="selection.id"
type="radio"
name="radio"
[checked]="selection.selected"
>
</td>
<td>{{ selection.selected }}</td>
</tr>
</table>
app.component.ts
import { Component } from '@angular/core';
import {CdkDragDrop, moveItemInArray, transferArrayItem, CdkDrag} from '@angular/cdk/drag-drop';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
drop(event: CdkDragDrop<string[]>) {
moveItemInArray(this.content, event.previousIndex, event.currentIndex);
}
content = [
{
"id": "1",
"selected": false
},
{
"id": "2",
"selected": false
},
{
"id": "3",
"selected": true
}
]
}
我认为 cdk/drag-drop 有问题。它不能正确处理拖动单选组。
它为无线电输入创建具有相同名称的克隆。浏览器将选择移动到克隆的元素。
我创建了一个 github issue for that bug as well as the dedicated PR 来解决这个问题。
至于现在,我可以建议您采用以下解决方法:
import { DragRef } from '@angular/cdk/drag-drop';
function patchCloneNode(method) {
const originalMethod = DragRef.prototype[method];
DragRef.prototype[method] = function() {
const sourceNode = this._rootElement;
const originalRadioInputs = sourceNode.querySelectorAll('input[type="radio"]');
const clonedNode = originalMethod.apply(this, arguments) as HTMLElement;
const clonedRadioInputs = clonedNode.querySelectorAll<HTMLInputElement>('input[type="radio"]');
Array.from(clonedRadioInputs).forEach((input, i) => {
input.name = originalRadioInputs[i].name + method;
});
return clonedNode;
}
}
patchCloneNode('_createPlaceholderElement');
patchCloneNode('_createPreviewElement');
我正在尝试使用 angular material 拖放组件重新排序基本无线电输入列表。
页面加载时,会检查正确的无线电输入。我的问题是,当我使用 [Grab] 句柄对列表中选中的项目重新排序时,单选选项似乎重置了,我不知道如何保留该选择。
对我来说真正奇怪的是,如果这是一个复选框,它会工作得很好。所以我假设这与我设置无线电输入的方式有关。
感谢您提供的任何帮助。
这是我的 stackblitz:https://stackblitz.com/edit/angular-2q94xh
app.component.html
<table cdkDropList (cdkDropListDropped)="drop($event)">
<tr *ngFor="let selection of content" cdkDrag>
<td>
<div class="grab" cdkDragHandle>[Grab]</div>
</td>
<td>
<input
[id]="selection.id"
type="radio"
name="radio"
[checked]="selection.selected"
>
</td>
<td>{{ selection.selected }}</td>
</tr>
</table>
app.component.ts
import { Component } from '@angular/core';
import {CdkDragDrop, moveItemInArray, transferArrayItem, CdkDrag} from '@angular/cdk/drag-drop';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
drop(event: CdkDragDrop<string[]>) {
moveItemInArray(this.content, event.previousIndex, event.currentIndex);
}
content = [
{
"id": "1",
"selected": false
},
{
"id": "2",
"selected": false
},
{
"id": "3",
"selected": true
}
]
}
我认为 cdk/drag-drop 有问题。它不能正确处理拖动单选组。
它为无线电输入创建具有相同名称的克隆。浏览器将选择移动到克隆的元素。
我创建了一个 github issue for that bug as well as the dedicated PR 来解决这个问题。
至于现在,我可以建议您采用以下解决方法:
import { DragRef } from '@angular/cdk/drag-drop';
function patchCloneNode(method) {
const originalMethod = DragRef.prototype[method];
DragRef.prototype[method] = function() {
const sourceNode = this._rootElement;
const originalRadioInputs = sourceNode.querySelectorAll('input[type="radio"]');
const clonedNode = originalMethod.apply(this, arguments) as HTMLElement;
const clonedRadioInputs = clonedNode.querySelectorAll<HTMLInputElement>('input[type="radio"]');
Array.from(clonedRadioInputs).forEach((input, i) => {
input.name = originalRadioInputs[i].name + method;
});
return clonedNode;
}
}
patchCloneNode('_createPlaceholderElement');
patchCloneNode('_createPreviewElement');