web-dev-qa-db-ja.com

angular ngModelで動的にmat-checkbox

オブジェクトの配列として1つのプロパティ「ユニット」を持つOfferクラスがあります。

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

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

私はAngular2を使用していますが、これらのユニットはユーザーが選択できるチェックボックスでなければなりません。また、angular material。

Htmlコードは次のようになります。

<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>    

Unitsプロパティは、次を使用してロードされます。

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));

フォームを送信するときに、checkedプロパティにチェック済みの値が含まれていません。

私は何を間違えていますか??

9
aldo

[checked]="unit.checked"を追加し、mat-checkboxからngModelid、およびnameを削除します。これは、ページをロードするときに一方向のバインディングを行いますが、双方向のバインディングを機能させるには、私のプロジェクトで行ったこのような何かを行う必要があります:

変更時に$eventを渡し、コンポーネントファイルの値を手動で設定します。

HTMLを次のように変更します。

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

これをコンポーネントファイルに追加します。

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:明示的に処理せずに双方向バインディングのソリューションを最近発見しました

model.unitscheckedのプロパティがあることを確認してください。これはそれを追加する最も簡単な方法です。

component.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>

有効/無効オプションを制御したい場合は、これを追加してみてください:

component.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>
10
Sri7

私にとってこの作品は、Angular 7。

名前が各チェックボックスで一意であることを確認するためだけに

<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>
7
San Jaisy

Angular 7でテストしましたが、あなたの質問に対してエラーを見つけることができず、作業デモを見ることができますこの中に StackBlitzの例 が、ここに私の答えがあります。

動作させるには、ngModelバインド入力に一意のnameを指定する必要があります。

コードを取得する例:

<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> 

これらの場合、配列表記を使用しないことを好みます(units[{{i}}])これは、すべてのフィールドが同じものに結合されていることを意味しますが、コードが機能しているように見えるため、これは単なる設定であり、エラーの原因ではありません。

2
Machado