在Angular 4中取消选中复选框后,如何从JSON数组中删除对象?

时间:2019-04-26 09:43:05

标签: javascript arrays angular typescript

0:
CategoryId: "31b7a227-9fda-4d14-8e1f-1dee5beeccb4"
Code: "GMA0300"
Description: "PA-5215: Renamed"
Enabled: true
Favorite: false
Id: "26cfdb68-ef69-4df0-b4dc-5b9c6501b0dd"
InstrumentType: null
Moniker: "1GMA0300"
Name: "Celiac Disease Panel (tTG IgG, tTG IgA, DGP IgG)"
Tests: Array(3)
  0:
   Code: "GMA0304"
   Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781"
   Name: "Deamidated Gliadin Peptide (DGP) IgG"
 __proto__: Object
  1: {Id: "2fcd610f-d453-4c4f-a8dc-1a5f50e88548", Code: "GMA0301", Name: 
 "Tissue Transglutaminase (tTG) IgA"}
  2: {Id: "de41b236-4866-419a-a6f4-5f7c1440d30f", Code: "GMA0302", Name: 
 "Tissue Transglutaminase (tTG) IgG"}
 length: 3
 __proto__: Array(0)
 TestsSelectable: false

嘿,这是一个数组selectedPanels对象,它具有另一个对象数组 我已经在面板中映射了这个,面板上有复选框,并且Tests是一个可扩展的行数组,也有复选框

当我选中面板复选框时,它会选中测试的所有子复选框,并显示测试的长度说3 但是,当我单击每个测试时,它应减去“测试长度”,即3-1 = 2,它现在应显示2 但是当我使用拼接时,当我取消选中每个测试复选框时,它会删除整行;或者当我单击每个测试时,已经实现的情况也是取消选中父面板复选框 我不知道该怎么办 我想要的是取消选择每个测试时 它不应删除文本,但应减少数组的长度

您可以从该图像中看到

image

这是我的html文件

<label class="custom-control custom-checkbox">
    <input type="checkbox" class="custom-control-input" [name]="panel.Id + '-' + panel.Moniker" [ngModel]="checkAllTestsSelected(panel)"
      (ngModelChange)="onPanelCheckboxUpdate($event, panel)" [id]="panel.Id + '-' + panel.Moniker">
    <span class="custom-control-indicator"></span>
  </label>

 </ng-template>
 <ng-template ngbPanelContent>
<div class="individual-panel" *ngFor="let test of panel.Tests">
  <span class="text-dimmed">{{test.Name}}</span>
  <span *ngIf="panel.Name.includes('ENA') || panel.Name.includes('Celiac')">
  <label class="custom-control custom-checkbox">
    <input type="checkbox" class="custom-control-input" [name]="test.Id + '-' + test.Code"
           [ngModel]="testSelectionSession.SelectedPanelIds.indexOf(panel.Id) > -1 || testSelectionSession.SelectedPanelIds.indexOf(test.AssociatedPanel?.Id) > -1"
           (ngModelChange)="onTestCheckboxUpdate($event, test, panel)" [id]="test.Id + '-' + test.Code">
    <span class="custom-control-indicator"></span>
  </label>
  </span>
</div>

ts文件

checkAllTestsSelected(panel: TestOrderPanel) {
  // get all individual test panels
  let individualTestPanelIds = panel.Tests.reduce((acc, test) => {
   if (test.AssociatedPanel) {
    acc.push(test.AssociatedPanel.Id);
  }
  return acc;
}, []);

// check if all individual test panels are selected
let allIndividualTestsSelected = individualTestPanelIds.reduce(
  (acc: boolean, panelId: number) =>
    acc && this.panelIds.indexOf(panelId) > -1,
  individualTestPanelIds.length > 0 &&
  panel.Tests.length === individualTestPanelIds.length
);

// if selected, remove all individual test panels and add the panel group
if (panel.Tests.length > 0 && allIndividualTestsSelected) {
  this.panelIds = this.panelIds.filter(
    panelId => individualTestPanelIds.indexOf(panelId) === -1
  );
  this.selectedPanels = this.selectedPanels.filter(
    selectedPanel => individualTestPanelIds.indexOf(selectedPanel.Id) === -1
  );
  this.panelIds.push(panel.Id);
  this.selectedPanels.push(panel);
  this.updateSession();
 }
  return this.panelIds.indexOf(panel.Id) > -1;
  }


 onPanelCheckboxUpdate($event: boolean, panel: TestOrderPanel) {
   let testPanelIds = panel.Tests.reduce((acc, test) => {
    if (test.AssociatedPanel) {
    acc.push(test.AssociatedPanel.Id);
  }

  return acc;
}, []);
// Wipe any duplicates
this.panelIds = this.panelIds.filter(
  panelId => panel.Id !== panelId && testPanelIds.indexOf(panelId) === -1
);
this.selectedPanels = this.selectedPanels.filter(
  selectedPanel =>
    panel.Id !== selectedPanel.Id &&
    testPanelIds.indexOf(selectedPanel.Id) === -1
);

if ($event) {
  this.panelIds.push(panel.Id);
  this.selectedPanels.push(panel);
   }
   this.updateSession();
 }

 onTestCheckboxUpdate($event: boolean,
                   test: TestOrderPanelTest,
                   panel: TestOrderPanel) {


let testPanelIds = panel.Tests.reduce((acc, test) => {
  if (test.AssociatedPanel) {
    acc.push(test.AssociatedPanel.Id);
  }

  return acc;
}, []);
let associatedTestPanels = this.testSelectionSession.IndividualTestPanelsForAll.filter(
  testPanel => testPanelIds.indexOf(testPanel.Id) > -1
);

let clickedTestPanel = associatedTestPanels.find(
  testPanel => (test.AssociatedPanel ? test.AssociatedPanel.Id : -1) === testPanel.Id
);


if (clickedTestPanel) {
  // Wipe any duplicates
  this.panelIds = this.panelIds.filter(
    panelId => clickedTestPanel.Id !== panelId
  );
  this.selectedPanels = this.selectedPanels.filter(
    panel => clickedTestPanel.Id !== panel.Id
  );

  // Add individual panel if checkbox selected
  if ($event) {
    this.panelIds = this.panelIds.concat(clickedTestPanel.Id);
    console.log(this.panelIds)
    this.selectedPanels = this.selectedPanels.concat(clickedTestPanel);
    console.log(this.selectedPanels)
  }
  }
  this.updateSession();
 }

数组在this.selectedPanels中 如何解决这个问题 有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

如果在模板的ngfor循环中添加索引(在下面的代码中为“ let i = index”),则可以将其传递给onTestCheckboxUpdate()函数,并在此时拼接源数组:

HTML文件:

<ul>
    <li *ngFor="let item of items; let i = index" [attr.data-index]="I">
        {{item}}
        <button (click)="removeItem(i)">Remove '{{item}}' from array</button>
    </li>
</ul>

TS文件:

items = ['cat','dog','mouse','frog','horse','bird'];

removeItem(itemIndex:number){
    this.items.splice(itemIndex, 1);
}

这是否达到您的期望?基本概念示例here

答案 1 :(得分:0)

您可以使用以下方法获取已检查或未检查的项目数。 已更新,将“已检查”属性添加到数据数组中Stackblitz下方和上方的每个项目。

TS文件:

items = [
    {name: 'cat'},
    {name: 'dog'},
    {name: 'horse'},
    {name: 'mouse'}
];

checkCount = this.items.length;

checkItem(itemIndex:number){
    if(this.items[itemIndex]['checked'] === undefined){
        this.items[itemIndex]['checked'] = false;
    } else {
        this.items[itemIndex]['checked'] = !this.items[itemIndex]['checked'];
    }
    this.checkCount = this.items.filter(item => item['checked'] === true || item['checked'] === undefined).length;
}

HTML文件:

<ul>
    <li *ngFor="let item of items; let i = index">
        <label>{{item.name}}</label>
        <input type="checkbox" checked (click)="checkItem(i)">
    </li>
</ul>

Check count: {{checkCount}}

示例here

如果需要双向绑定,则可以使用formControl来保存每个复选框的“ checked”变量,而不是普通的布尔值。您可以看到此here的示例。