it-swarm.com.de

winkelmatte-checkbox dynamisch mit ngModel

Ich habe eine Klasse Offer, die eine Eigenschaft "units" als Array von Objekten hat.

export class Offer {
   public propertyA: string;
   public propertyB: string;
   public units: Unit[];
}

export class Unit {    
    public code: string,
    public name: string,
    public checked: boolean
}

Ich verwende Angular2, diese Einheiten müssen Kontrollkästchen sein, die der Benutzer auswählen kann Ich verwende auch eckiges Material.

Der HTML-Code sieht folgendermaßen aus:

<div *ngFor="let unit of model.units; let i=index">
  <mat-checkbox [(ngModel)]="model.units[i].checked"
    id="units[{{i}}]" name="units[{{i}}]">
       {{ unit.name }}
  </mat-checkbox>                        
</div>    

Die Einheiteneigenschaft wird geladen mit:

this.model.units.Push(new Unit("code1","name1", false));
this.model.units.Push(new Unit("code2","name2", false));
this.model.units.Push(new Unit("code3","name3", false));

Beim Senden des Formulars enthält die geprüfte Eigenschaft nicht den geprüften Wert.

Was mache ich falsch??

6
aldo

Fügen Sie [checked]="unit.checked" hinzu und entfernen Sie ngModel, id und name aus Ihrem mat-checkbox. Dies funktioniert zwar in eine Richtung, wenn Sie die Seite laden, aber um die bidirektionale Bindung auszuführen, müssen Sie etwas Ähnliches wie das in meinem Projekt ausführen:

Übergeben Sie den $event bei Änderung und legen Sie den Wert in der Komponentendatei manuell fest:

Ändern Sie Ihren HTML-Code in:

<div *ngFor="let unit of model.units">
  <mat-checkbox [checked]="unit.checked" 
  (change)="valueChange(model.units,unit,$event)">
       {{ unit.name }}
  </mat-checkbox>                        
</div>

Fügen Sie dies zur Komponentendatei hinzu:

valueChange(model.units, unit, $event) {
        //set the two-way binding here for the specific unit with the event
        model.units[unit].checked = $event.checked;
    }

EDIT/UPDATE : Kürzlich eine Lösung für die bidirektionale Bindung gefunden, ohne explizit damit umzugehen

Stellen Sie sicher, dass model.units eine Eigenschaft für checked besitzt. Dies ist der einfachste Weg, um es hinzuzufügen: 

komponente.ts:

this.model.units.forEach(item => {
                       item.checked = false; //change as per your requirement
                    });

html:

 <div *ngFor="let unit of model.units;let i=index">
    <mat-checkbox [(ngModel)]="unit.checked" [checked]="unit.checked"                                                                                    
    name="{{i}}-name">  //make sure name is unique for every item                             
    </mat-checkbox>
</div>

Wenn Sie auch die Aktivierungs-/Deaktivierungsoptionen steuern möchten, fügen Sie Folgendes hinzu:

komponente.ts:

this.model.units.forEach(item => {
                       item.checked = false;//change as per your requirement
                       item.disabled = true;//change as per your requirement
                        });

html:

<div *ngFor="let unit of model.units;leti=index">
        <mat-checkbox [(ngModel)]="unit.checked" [checked]="unit.checked"
         [disabled]="unit.disabled"                                                                                    
       name="{{i}}-name">//make sure name is unique for every item
        </mat-checkbox>
    </div>
7
Sri7

Diese Arbeit wurde für mich in Angular 7 getestet.

Nur um sicherzustellen, dass der Name für jedes Kontrollkästchen eindeutig ist

<mat-grid-list cols="4" rowHeight="100px">
                    <mat-grid-tile *ngFor="let item of aspNetRolesClaims" [colspan]="1" [rowspan]="1">
                        <span>{{item.claimValue}}</span>
                        <mat-checkbox [(ngModel)]="item.claimValue" name="{{item.claimType}}">{{item.claimType}}</mat-checkbox>
                    </mat-grid-tile>
                </mat-grid-list>
1
San Jaisy

Ich habe es in Angular 7 getestet und konnte bei Ihrer Frage keinen Fehler finden. In diesem StackBlitz-Beispiel können Sie jedoch eine Arbeitsdemo sehen, aber hier geht meine Antwort.

Um funktionieren zu können, müssen Sie Ihrer ngModel-gebundenen Eingabe eine eindeutige name geben.

Beispiel für Ihren Code:

<div *ngFor="let unit of model.units; let i=index">
  <mat-checkbox 
    [(ngModel)]="model.units[i].checked"
    id="units-{{i}}" 
    name="units-{{i}}" // using plain slug-case instead of array notation
  >
      {{ unit.name }}
  </mat-checkbox>                        
</div> 

Ich ziehe es vor, die Array-Notation in diesen Fällen nicht zu verwenden (units[{{i}}]), da dies bedeutet, dass alle Felder auf dieselbe Weise verbunden sind. Da Ihr Code jedoch zu funktionieren scheint, ist dies nur eine Präferenz und nicht die Ursache des Fehlers.

0
Machado