You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中mat-checkbox选中时Array.push仅存最后一项的问题修复请求

问题原因

每个<app-item>都是独立的组件实例,各自维护自己的ArrayChecked数组。选中复选框时,只是往当前item组件的数组里添加内容,其他item组件的数组不会同步,所以日志里只会显示当前item的那一项。

修复方案

把选中项的管理逻辑提升到父组件ItemListComponent,子组件只负责传递选中状态的变化,由父组件统一维护所有选中项的数组。

1. 修改子组件 item.component.ts

移除子组件内的ArrayChecked,添加@Output事件发射器,向父组件传递选中/取消选中的任务信息:

import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';

@Component({
  selector: 'app-item',
  templateUrl: './item.component.html',
  styleUrls: ['./item.component.scss'],
})
export class ItemComponent implements OnInit {
  @Input() value: any;
  @Input() isChecked: boolean; // 由父组件控制选中状态
  @Output() checkChange = new EventEmitter<{ task: string; checked: boolean }>();

  constructor() {
    this.isChecked = false;
  }

  ngOnInit(): void {}

  onChange($event: any) {
    this.checkChange.emit({
      task: this.value.task,
      checked: $event.checked
    });
  }
}

2. 修改子组件模板 item.component.html

把[(ngModel)]绑定改成从父组件传入的isChecked,避免子组件自己维护状态:

<div class="listContainer">
  <div class="checkContainer">
    <mat-checkbox color="secondary" [checked]="isChecked" (change)="onChange($event)"> 
    </mat-checkbox>
  </div>
</div>

<div class="displayTask">
 <div class="displayvalue" [ngClass]="{ 'line-through': isChecked }">
  {{ value.task | uppercase }}
 </div>
</div>

(注:原模板里[ngClass]的判断条件value.task不符合逻辑,改成isChecked才是选中时划线的正确逻辑)

3. 修改父组件 item-list.component.ts

添加选中项数组,处理子组件发来的事件:

import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'app-item-list',
  templateUrl: './item-list.component.html',
  styleUrls: ['./item-list.component.scss'],
})
export class ItemListComponent implements OnInit {
  nameControl = new FormControl('');
  data: { task: string }[] = []; // 假设你的任务数据结构为包含task字段的对象数组
  arrayChecked: string[] = []; // 统一维护所有选中项

  constructor() {}

  ngOnInit(): void {}

  addTask() {
    const task = this.nameControl.value?.trim();
    if (task) {
      this.data.push({ task });
      this.nameControl.reset();
    }
  }

  onItemCheckChange(event: { task: string; checked: boolean }) {
    if (event.checked) {
      // 添加选中项,避免重复
      if (!this.arrayChecked.includes(event.task)) {
        this.arrayChecked.push(event.task);
      }
    } else {
      // 移除取消选中的项
      this.arrayChecked = this.arrayChecked.filter(task => task !== event.task);
    }
    console.log('所有选中项:', this.arrayChecked);
  }
}

4. 修改父组件模板 item-list.component.html

给<app-item>绑定isChecked输入和checkChange输出事件:

<div>
  <mat-form-field appearance="outline">
    <input matInput placeholder="Add a Task" (keyup.enter)="addTask()" autocomplete="off" [formControl]="nameControl"/>
  </mat-form-field>
</div>

<app-item
  [value]="value"
  [isChecked]="arrayChecked.includes(value.task)"
  (checkChange)="onItemCheckChange($event)"
  *ngFor="let value of data; index as index"
>
</app-item>
逻辑说明
  • 父组件ItemListComponent维护唯一的arrayChecked数组,所有选中项都存储在这里。
  • 每个子组件ItemComponent的选中状态由父组件通过[isChecked]传入,确保所有item的状态统一。
  • 子组件触发复选框变化时,通过checkChange事件把任务和选中状态传给父组件,父组件负责更新数组。
  • 父组件在更新数组时做了去重和过滤处理,避免重复添加或残留已取消选中的项。

内容的提问来源于stack exchange,提问作者Joskaa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 05:20:32