简体   繁体   English

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

[英]How to remove an object from JSON array when checkbox is deselected in Angular 4?

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

hey this is an array selectedPanels object which has another array of objects i have mapped this in panel and panel has checkbox and Tests which is an array is expandable rows and has also checkbox 嘿,这是一个数组selectedPanels对象,它有另一个对象数组,我已经在面板和面板中映射了它有复选框和测试,这是一个数组是可扩展的行,也有复选框

when i check the panel checkbox it checks all the child checkboxes of Tests and shows the length of Tests say 3 but when i click on each test it should be minus from Tests length say 3 - 1 = 2 it should show 2 now but when i use splice it removes the whole row when i deselect the the each test checkbox or the already implementation is when i click on each test it deselect the parent panel checkbox too i dont know what to what is want is when i deselect the each test it should not remove the text but decrease the length of array 当我检查面板复选框时,它检查测试的所有子复选框,并显示测试的长度说3但是当我点击每个测试它应该是从测试长度减去说3 - 1 = 2它现在应该显示2但是当我当我取消选择每个测试复选框时,使用splice它将删除整行,或者当我点击每个测试时它取消选择父面板复选框,我也不知道当我取消选择每个测试时应该是什么不删除文本但减少数组的长度

you can see from that image 你可以从那个图像看到

image 图片

here is my html file 这是我的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 file 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();
 }

array is in this.selectedPanels how to solve this issue can anyone help? 数组是在this.selectedPanels中如何解决这个问题可以有人帮忙吗?

If you add an index to the ngfor loop in your template ('let i = index' in the code below), you can pass this to your onTestCheckboxUpdate() function and splice the source array at this point: 如果向模板中的ngfor循环添加索引(在下面的代码中为'let i = index'),则可以将其传递给onTestCheckboxUpdate()函数并在此处拼接源数组:

HTML file: 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 file: TS档案:

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

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

Does this achieve what you're looking for? 这会实现您的目标吗? Example of the basic concept here . 这里的基本概念示例。

You can use the following approach to get the number of items which are checked, or not checked. 您可以使用以下方法获取已检查或未选中的项目数。 Updated to add 'checked' property to each item in data array, below and on Stackblitz . 更新为将'checked'属性添加到数据数组中的每个项目,下面和Stackblitz上

TS File: 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 File: 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}}

Example here . 这里的例子。

If you needed two-way binding, you could use a formControl to hold the 'checked' variable for each checkbox, rather than a plain boolean. 如果需要双向绑定,可以使用formControl来保存每个复选框的“checked”变量,而不是普通的布尔值。 You can see an example of this here . 你可以在这里看到一个例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM