【问题标题】:How to remove an item of an array when deselecting the checkbox (angular 4)取消选中复选框时如何删除数组的一项(角度4)
【发布时间】:2019-05-25 20:30:11
【问题描述】:

我有这个对象数组。在每个对象中都有另一个数组。

panels = [{
  Id: "26cfdb68-ef69-4df0-b4dc-5b9c6501b0dd",
  Name: "Celiac test",
  Tests: [{
      Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
      Name: "test 1 (DGP) IgG"
    },
    {
      Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
      Name: "test 2 (DGP) IgG"
    },
    {
      Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
      Name: "test 3 (DGP) IgG"
    }
  ]
}],

我已将它映射到带有复选框的引导手风琴。

首先是主对象的复选框,然后是该对象中的数组的复选框。

我想要的是,当我单击主面板复选框时,它应该选择测试复选框并将面板对象保存在对象变量中,例如 selectedPanel,当我取消选择主面板时也应该取消选中所有的测试复选框。

我可以做到,但主要的是,当我取消选择其中一个测试复选框时,它应该从 selectedPanel 和长度中删除。

有人可以在这方面帮助我吗?

我也创建了一个堆栈闪电战:

Stackblitz

【问题讨论】:

  • 所以当我取消选中你想从panels 数组中删除元素的复选框时,我正确吗?
  • 是的,这就是我想要的@YashRami
  • @usmansaleem 你想要这个吗?stackblitz.com/edit/angular-bslndo
  • 是的,但是如何将它添加到 selectedPanel 变量中,当我回来进行编辑时,它应该保持原样?
  • 你会选择Panel 保存整个类别对象还是只是一个测试子对象?

标签: javascript angular typescript checkbox accordion


【解决方案1】:

你可以这样试试。

<ngb-accordion #acc="ngbAccordion">
  <ngb-panel *ngFor="let panel of panels; let i = index" id="{{panel.Id}}" [title]="panel.Name">
     <ng-template ngbPanelTitle>
        <span class="panel-length"><strong>{{panel.Tests.length}}</strong></span>

            <input type="checkbox" class="form-check-input ml-5" id="{{panel.Id}}" name="{{panel.Name}}">


      </ng-template>
    <ng-template ngbPanelContent>
    <div class="individual-panel" *ngFor="let test of panel.Tests, let j = index;">
          <span class="text-dimmed">{{test.Name}}</span>
            <input type="checkbox" class="form-check-input ml-5" id="{{test.Id}}" name="{{test.Name}}" (click)="checkItem(i, j)">  
        </div>
    </ng-template>
  </ngb-panel>
</ngb-accordion>

   <!-- <span class="panel-length"><strong>{{panels.Tests.length}}</strong></span> -->

TS

checkItem(i, j){
   this.panels[i].Tests.splice(j, 1);
   console.log(this.panels[i].Tests);
  }

希望对你有帮助。

【讨论】:

  • 它正在从数组中删除整行。
【解决方案2】:

我创建了一个简短的 Stackblitz 演示 HERE

它使用 parent 控制子复选框的切换,每个复选框都有一个 checked 参数来跟踪选择了哪个。

这将使您更容易维护每个复选框的状态,而不是操纵每个更改。

【讨论】:

  • 是的,但是如何将它添加到 selectedPanel 变量中,当我回来进行编辑时,它应该保持原样?
【解决方案3】:

Stackblitz:https://stackblitz.com/edit/angular-bsszc9?file=src/app/app.component.ts

请注意,下面的代码是您可以使用的技术的一个简单示例。

我给测试一个 isShown 属性。注意:您应该将这些测试重构为带有单独模块的对象。

panels = [{
  CategoryId: "31b7a227-9fda-4d14-8e1f-1dee5beeccb4",
  Id: "26cfdb68-ef69-4df0-b4dc-5b9c6501b0dd",
  Name: "Celiac test",
  Tests: [
  {Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 1 (DGP) IgG", 
   isShown: true },
  {
   Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 2 (DGP) IgG", 
   isShown: true },
  {
   Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 3 (DGP) IgG", 
   isShown: true}
]
},
{
  CategoryId: "31b7a227-9fda-4d14-8e1f-1dee5beeccb4",
  Id: "26cfdb68-ef69-4df0-b4dc-5b9c6501b0dd",
  Name: "Comprehensive test",
  Tests: [
  {Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 1  (DGP) IgG"},
  {
   Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 2  (DGP) IgG"},
  {
   Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
   Name: "test 3  (DGP) IgG"}
]
}]

当您单击输入框时,会触发单击事件并将test.isShown 属性设置为false*ngIf 将从显示的代码中隐藏测试。 (请注意,我引入了一个新的 ng-container,因为您不能在同一个容器上使用 *ngFor*ngIf)。

<ng-container *ngFor="let test of panel.Tests">
  <div class="individual-panel" *ngIf='test.isShown'>
    <span class="text-dimmed">{{test.Name}}</span>
    <input type="checkbox" class="form-check-input ml-5" id="{{test.Id}}" name="{{test.Name}}" (click)="hide( test )" >   
  </div>
</ng-container>

下面是点击事件触发的方法。或者,您可以将 test 从数组中删除(这将使您的计数器工作,但擦除数据可能不是一个好主意);

hide( test ) {
  test.isShown = false;
}

最后,这个答案是为了向您展示这种简单的技术。您显然希望重构更小的类/模块并使其更易于维护。希望它有所帮助;)。

【讨论】:

    【解决方案4】:

    首先,您需要向panelsTests 添加一个额外的属性来存储复选框的状态。 你panels 数组会是这样的:

    panels = [{
      Id: "26cfdb68-ef69-4df0-b4dc-5b9c6501b0dd",
      Name: "Celiac test",
      checked: false,
      Tests: [{
          Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
          Name: "test 1 (DGP) IgG",
          checked: false
        },
        {
          Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
          Name: "test 2 (DGP) IgG",
          checked: false
        },
        {
          Id: "e2bb4607-c227-4483-a3e9-55c1bc5a6781",
          Name: "test 3 (DGP) IgG",
          checked: false
        }
      ]
    }]
    

    其次,您需要检查复选框的值,以决定是否要将特定测试保留在 selectedPanel 中。

    我假设您的 panelsTests 具有唯一的 Id 属性

    您可以找到 stackblitz here

    的更新版本

    我希望这是您想要实现的行为。

    【讨论】:

    • 如果没有来自后端的检查并且它不工作,因为它不允许我添加 2 个或更多面板,只有一个也可以操作我的代码,以便我可以理解它更好的 codeshare.io/Gq97kM panelIds 是所有面板的 id 和 selectedPanels 具有整个对象数组的那个
    • 因为我在下一页显示了所选测试的长度,它给了我错误 let rollup = session.SelectedPanels.reduce((memo, panel) => { memo[panel.CategoryId] = (memo [panel.CategoryId] || 0) + (panel.Tests.length > 0 ? panel.Tests.length : 1); return memo; }, {}); this.categoryRollup = session.SelectedPanels.length > 0 ? Object.assign({}, this.categoryRollup, rollup) : {};
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多