Я пытаюсь заполнить выбранные значения переключателей каждой строки как true или false и сформировать объект для отправки.
Чтобы различать значения переключателей каждой строки, для тега переключателя было задано значение {{k}}+{{sizeobj.rbSelected}}
, которое вызывает проблему, и обновление модели как k + false, затем k + k + false и т. Д. Для последующих щелчки.
Проблема в логике в методе onSelectionChange(..)
. Предполагается, что onSelectionChange () обновляет JSON значениями true / false для выбранных переключателей каждой строки, чтобы иметь возможность отправить JSON обратно на сервер посредством вызова службы POST API.
Код:
import { Component, ChangeDetectorRef } from '@angular/core';
import {
FormsModule, AbstractControl, ControlValueAccessor, FormBuilder, FormGroup, Validators,
FormControl, NG_VALUE_ACCESSOR, Validator, NgForm
} from '@angular/forms';
@Component({
selector: 'my-app',
template: `
<table>
<tbody *ngFor="let redeempointdeliverable of redeempointsdata; let i=index;">
<tr>
<td>
<div class="form-group">
<input type="checkbox" name="allCB[{{i}}]" [checked]="isAllChecked(i)" (change)="checkAll($event, i)"
[(ngModel)]="redeempointdeliverable.mainCBChecked" required>
</div>
</td>
<td colspan="6">
</td>
</tr>
<tr *ngFor="let catalog of redeempointdeliverable.itemCatalog; let j=index;">
<td></td>
<td>
<div class="form-group">
<input [ngModelOptions]="{standalone: true}" type="checkbox" value="{{catalog.id}}"
[(ngModel)]="catalog.subCBChecked" [checked]="catalog.subCBChecked" (change)="checkSub($event, i, j)"
required>
</div>
</td>
<td></td>
<td *ngFor="let sizeobj of catalog.itemSize; let k=index;">
<div class="form-group">
<input type="radio" name={{catalog.itemType}}+{{j}}+{{i}} value={{k}}+{{sizeobj.rbSelected}}
[(ngModel)]=sizeobj.rbSelected [checked]="sizeobj.rbSelected"
(change)="onSelectionChange($event, i, j, k)"
required> {{sizeobj.size}}
</div>
{{sizeobj.rbSelected}}
</td>
<td></td>
</tr>
</tbody>
</table>
`
})
export class AppComponent {
name = 'Angular';
redeempointsdata: any;
constructor(private ref: ChangeDetectorRef) {
this.redeempointsdata = [
{
'itemCatalog': [
{
'itemSize': [
{
'size': 'SMALL',
'rbSelected': false
},
{
'size': 'MEDIUM',
'rbSelected': false
},
{
'size': 'LARGE',
'rbSelected': false
}
],
'subCBChecked': false
},
{
'itemSize': [
{
'size': 'SMALL',
'rbSelected': false
},
{
'size': 'MEDIUM',
'rbSelected': false
},
{
'size': 'LARGE',
'rbSelected': false
}
],
'subCBChecked': false
},
{
'itemSize': [
{
'size': 'SMALL',
'rbSelected': false
},
{
'size': 'MEDIUM',
'rbSelected': false
},
{
'size': 'LARGE',
'rbSelected': false
}
],
'subCBChecked': false
}
],
'mainCBChecked': false
},
{
'itemCatalog': [
{
'itemSize': [
{
'size': 'SMALL',
'rbSelected': false
},
{
'size': 'MEDIUM',
'rbSelected': false
},
{
'size': 'LARGE',
'rbSelected': false
}
],
'subCBChecked': false
}
],
'mainCBChecked': false
}
];
}
onSelectionChange(ev, i, j, k) {
this.getItemCatalogs()[i].itemCatalog[j].itemSize[k].rbSelected = ev.target.checked;
// this.ref.detectChanges();
for (let l = 0; l < this.redeempointsdata.length; l++) {
const rpObjAr = this.redeempointsdata[l].itemCatalog;
for (let m = 0; m < rpObjAr.length; m++) {
const sizeAr = rpObjAr[m].itemSize;
for (let n = 0; n < sizeAr.length; n++) {
const sizeObj = sizeAr[n];
console.log('sizeObj.rbSelected = ' + sizeObj.rbSelected);
if (n === k) {
continue;
} else if (n !== k) {
this.getItemCatalogs()[i].itemCatalog[j].itemSize[n].rbSelected = false;
}
}
}
}
}
getItemCatalogs() {
const rpData = [];
let rpObj = {};
for (let i = 0; i < this.redeempointsdata.length; i++) {
rpObj = this.redeempointsdata[i];
console.log('rpObj: ' + JSON.stringify(rpObj));
rpData.push(rpObj);
}
console.log('rpData: ' + JSON.stringify(rpData));
return rpData;
}
checkAll(ev, i) {
let count = 0;
this.getItemCatalogs()[i].itemCatalog.forEach(x => {
x.subCBChecked = ev.target.checked;
if (x.subCBChecked) {
count++;
}
});
console.log('count of checkboxes checked: ' + count);
return count;
}
isAllChecked(i) {
console.log('fired');
return this.getItemCatalogs()[i].itemCatalog.every(_ => _.subCBChecked);
}
checkSub(ev, i, j) {
let mainCheckVal = true;
const rpDataAr = this.getItemCatalogs();
const x = rpDataAr[i].itemCatalog;
for (j = 0; j < x.length; j++) {
if (x[j].subCBChecked === true) {
mainCheckVal = mainCheckVal && x[j].subCBChecked;
} else {
mainCheckVal = false;
}
}
this.getItemCatalogs()[i].mainCBChecked = mainCheckVal;
console.log('mainCheckVal: ' + mainCheckVal);
return mainCheckVal;
}
}
Теперь я могу заполнить соответствующие значения true или false для выбранных переключателей в объекте JSON с указанными выше изменениями кода, что можно проверить по приведенной ниже ссылке, но все еще сталкивается с проблемой, т.е. щелкнуть каждый переключатель дважды, чтобы выбрать его. Благодарим вас за помощь в решении этой проблемы.
Рабочая плункерная ссылка:
https://plnkr.co/edit/Nwz96APdaXdOXUuZ?preview
Ссылка на изображение макета экрана:
Вложенная таблица с флажком и набором переключателей для каждой строки
PS: Мне нужно это с вышеупомянутым JSON или моделью данных (или, если нет, с минимально возможными изменениями, так как это трудно изменить), которое получается посредством вызова службы из серверной части.