Angular 使用角度材质拖放时,无线电输入选择将重置

Angular 使用角度材质拖放时,无线电输入选择将重置,angular,input,angular-material,radio-button,angular-cdk-drag-drop,Angular,Input,Angular Material,Radio Button,Angular Cdk Drag Drop,我正在尝试使用“角度材质拖放”组件对基本无线电输入列表进行重新排序 当页面加载时,将检查正确的无线电输入。我的问题是,当我使用[Grab]句柄对列表中的选中项重新排序时,无线电选择似乎会重置,我无法确定如何保持选择 对我来说,真正奇怪的是,如果这是一个复选框,它会工作得很好。所以我假设这与我设置无线电输入的方式有关 感谢您能提供的任何帮助 这是我的闪电战: app.component.html <table cdkDropList (cdkDropListDropped)="dr

我正在尝试使用“角度材质拖放”组件对基本无线电输入列表进行重新排序

当页面加载时,将检查正确的无线电输入。我的问题是,当我使用[Grab]句柄对列表中的选中项重新排序时,无线电选择似乎会重置,我无法确定如何保持选择

对我来说,真正奇怪的是,如果这是一个复选框,它会工作得很好。所以我假设这与我设置无线电输入的方式有关

感谢您能提供的任何帮助

这是我的闪电战:

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>

[抓取]
{{selection.selected}}
应用程序组件.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
  }
]
}
从'@angular/core'导入{Component};
从“@angular/cdk/drag drop”导入{CdkDragDrop,moveItemInArray,transferArrayItem,CdkDrag}”;
@组成部分({
选择器:“我的应用程序”,
templateUrl:“./app.component.html”,
样式URL:['./app.component.css']
})
导出类AppComponent{
drop(事件:CdkDragDrop){
moveItemInArray(this.content、event.previousIndex、event.currentIndex);
}
内容=[
{
“id”:“1”,
“选定”:false
},
{
“id”:“2”,
“选定”:false
},
{
“id”:“3”,
“选定”:真
}
]
}

我认为这是cdk/拖放的问题。它无法正确处理拖动无线电组的问题

它为无线电输入创建具有相同名称的克隆。浏览器会将所选内容移动到克隆的元素

我为这个bug创建了一个新的程序来修复它

就目前而言,我可以向您建议以下解决方法:

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/cdk/drag-drop'导入{DragRef};
函数克隆节点(方法){
const originalMethod=DragRef.prototype[method];
prototype[method]=function(){
const sourceNode=this.\u rootElement;
const originalradionputs=sourceNode.queryselectoral('input[type=“radio”]”);
const clonedNode=originalMethod.apply(这个,参数)作为HTMLElement;
const clonedrionputs=clonedNode.querySelectorAll('input[type=“radio”]”);
Array.from(clonedRadioInputs).forEach((输入,i)=>{
input.name=原始放射性输入[i].name+方法;
});
返回克隆节点;
}   
} 
patchCloneNode(“创建占位符元素”);
patchCloneNode(“创建预览元素”);

一个问题是视图和模型不同步。更改模型时,将其发送到带有
[checked]=“selection.selected”
的值,但当视图更改时,您还必须更新模型,订阅
(change)=“selection.selected=$event.target.checked”
。但是,即使修复了这个问题,视图仍然会丢失checked属性(而模型会保留它),这很奇怪,感谢您的回复,并完全同意您的意见。在我的匆忙中,我错误地从我的主代码中删除了(更改),因为它正在做一系列其他的事情,并且,正如你所说的,似乎并不是问题的根本原因。请注意,对于其他人来说,切换到角度材质似乎可以消除这个问题,尽管它最多感觉像是一个解决方法。太棒了。现在效果很好。非常感谢。