简体   繁体   English

为什么切换一个复选框也会切换其他一些复选框?

[英]Why does toggling one checkbox also toggle some others?

I built a table component.我构建了一个表格组件。 User can select which columns he wants to see.用户可以选择他想要查看的列。

You can try it on StackBlitz.你可以在 StackBlitz 上试一试。 Doesn't look nice without all the SCSS, but it shows the same phenomenon.没有所有的 SCSS 看起来不太好,但它显示了相同的现象。 https://stackblitz.com/edit/angular-she4fk https://stackblitz.com/edit/angular-she4fk

At start, only three checkboxes are checked, and the appropriate columns are visible.开始时,只选中了三个复选框,并且相应的列是可见的。

When I toggle any one checkbox, the column gets shown or hidden, but other checkboxes get checked/unchecked as well.当我切换任何一个复选框时,该列会显示或隐藏,其他复选框也会被选中/取消选中。 The columns are shown correctly, but the checkboxes are completely wrong.列显示正确,但复选框完全错误。 I don't see the problem, especially because the table and the underlying array behave as expected!我没有看到问题,特别是因为表和底层数组的行为符合预期!

For this example, I begin in Frame 1 with the columns First name , Sur name and Department visible (and the corresponding checkboxes checked).对于此示例,我从第Frame 1开始,其中First nameSur nameDepartment可见(并选中相应的复选框)。 Then I set the Selection checkbox: on-off-on.然后我设置Selection复选框:开-关-开。 Every time, other checkboxes react (without the underlying array being changed).每次,其他复选框都会做出反应(不更改底层数组)。

I would like to understand why.我想了解为什么。 And most importantly: How can I stop the other boxes from reacting?最重要的是:我怎样才能阻止其他盒子做出反应? (Maybe interesting sidenote: The pattern is reproducible. When I reload the app (F5) and select the Selection checkbox, I can always reproduce these exact same "Frames 1-4". So the behaviour of the other checkboxes is not random.) (也许有趣的旁注:该模式是可重现的。当我重新加载应用程序 (F5) 并选中“ Selection复选框时,我始终可以重现这些完全相同的“第 1-4 帧”。因此其他复选框的行为不是随机的。)

更改“选择”复选框选中/取消选中其他复选框

Here is the code, pretty straight forward.这是代码,非常简单。

export class AppComponent  {
    fieldTitle: string[] = [];
    fieldVisibility: boolean[] = [];

    constructor()
    {
        this.fieldTitle[0] = 'Selection';
        this.fieldTitle[1] = 'Personal number';
        this.fieldTitle[2] = 'Salutation';
        this.fieldTitle[3] = 'First name';
        this.fieldTitle[4] = 'Last name';
        this.fieldTitle[5] = 'Department';
        this.fieldTitle[6] = 'Company';

        this.fieldVisibility[0] = false;
        this.fieldVisibility[1] = false;
        this.fieldVisibility[2] = false;
        this.fieldVisibility[3] = true;
        this.fieldVisibility[4] = true;
        this.fieldVisibility[5] = true;
        this.fieldVisibility[6] = false;
    }

    toggleVisibility(fieldIdx: number) {
        console.log(fieldIdx + ' BEFORE toggle: ' + JSON.stringify(this.fieldVisibility));
        this.fieldVisibility[fieldIdx] = !this.fieldVisibility[fieldIdx];
        console.log(fieldIdx + ' AFTER  toggle: ' + JSON.stringify(this.fieldVisibility));
    }

    isVisible(fieldIdx: number) {
        console.log(fieldIdx + ' is ' + (this.fieldVisibility[fieldIdx] ? 'visible' : 'hidden'));
        return this.fieldVisibility[fieldIdx];
    }
}

And the template:和模板:

<table>
    <tr>
        <ng-container *ngFor="let visible of fieldVisibility; index as i;">
            <th *ngIf="visible">{{fieldTitle[i]}}</th>
        </ng-container>

        <th>
            <ul>
                <!-- solution: "let dummy of fieldTitle; index as i" -->
                <li *ngFor="let visible of fieldVisibility; index as i">
                    <label>
                        <input (change)="toggleVisibility(i)"
                              [checked]="isVisible(i)"
                              type="checkbox">
                        {{fieldTitle[i]}}
                    </label>
                </li>
            </ul>
        </th>
    </tr>
</table>

Use the fieldTitle array in the *ngFor instead of fieldVisibility .*ngFor使用fieldTitle数组而不是fieldVisibility Like this: <ng-container *ngFor="let visible of fieldTitle; index as i">像这样: <ng-container *ngFor="let visible of fieldTitle; index as i">

you can not iterate over the same element you want to change, if you iterate over你不能迭代你想要改变的同一个元素,如果你迭代

<ng-container *ngFor="let visible of [0,1,2,3,4,5,6]; let i=index">

You has no problen.你没有问题。 Even if you decided has only an unique array like即使您决定只有一个唯一的数组,例如

fields=[
      {title: 'Selection',visibility:false},
        {title: 'Personal number',visibility:false},
        {title: 'Salutation',visibility:false},
        {title: 'First name',visibility:true},
        {title: 'Last name',visibility:true},
        {title: 'Department',visibility:true},
        {title: 'Company',visibility:false}
    ]

You can do你可以做

<ng-container *ngFor="let field of fields; index as i;">
    <th *ngIf="field.visibility">{{fieldTitle[i]}}</th>
</ng-container>

(see that we can use field.visibility and field.title) (看到我们可以使用 field.visibility 和 field.title)

And

<input [(ngModel)]="field.visibility"
    [name]="'fieldSelectId'+i" 
    class="form-check-input" [id]="'fieldSelect'+i" type="checkbox" >

In this case you don't violate the rule "can not iterate over an element you change" because you change the "propertie" of an object, no the object itself在这种情况下,您不会违反“无法迭代您更改的元素”的规则,因为您更改了对象的“属性”,而不是对象本身

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

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